sql-server - SQL中的Vlookup
问题描述
我正在尝试编写一个查询,它将为帐户代码的每个段提取描述。该表如下所示:
我想要做的是让每个 CTRC 部分为匹配的 CTACCT 提取 CTDESC 示例:
我的原始数据有超过 400 万行,所以我无法导出到 excel 以进行正常的 Vlookup。我只有一张包含所有这些数据的表,并且无法进行自我连接以提取所有行,我一次只能做一个部分。
SELECT TOP 10
RTRIM(a.CTACCT) AS [CTACCT],
RTRIM(a.CTRC01) AS [CTRC01],
NULLIF(CONCAT(RTRIM(a.CTrc01), '-', RTRIM(a.CTrc02)), CONCAT(RTRIM(a.CTrc01), '-')) AS [CTRC02],
NULLIF(CONCAT(RTRIM(a.CTrc01), '-', RTRIM(a.CTrc02), '-', RTRIM(a.CTrc03)), CONCAT(RTRIM(a.CTrc01), '-', RTRIM(a.CTrc02), '-')) AS [CTRC03],
NULLIF(CONCAT(RTRIM(a.CTrc01), '-', RTRIM(a.CTrc02), '-', RTRIM(a.CTrc03), '-', RTRIM(a.CTrc04)), CONCAT(RTRIM(a.CTrc01), '-', RTRIM(a.CTrc02), '-', RTRIM(a.CTrc03), '-')) AS [CTRC04],
NULLIF(CONCAT(RTRIM(a.CTrc01), '-', RTRIM(a.CTrc02), '-', RTRIM(a.CTrc03), '-', RTRIM(a.CTrc04), '-', RTRIM(a.CTrc05)), CONCAT(RTRIM(a.CTrc01), '-', RTRIM(a.CTrc02), '-', RTRIM(a.CTrc03), '-', RTRIM(a.CTrc04), '-')) AS [CTRC05],
NULLIF(CONCAT(RTRIM(a.CTrc01), '-', RTRIM(a.CTrc02), '-', RTRIM(a.CTrc03), '-', RTRIM(a.CTrc04), '-', RTRIM(a.CTrc05), '-', RTRIM(a.CTrc06)), CONCAT(RTRIM(a.CTrc01), '-', RTRIM(a.CTrc02), '-', RTRIM(a.CTrc03), '-', RTRIM(a.CTrc04), '-', RTRIM(a.CTrc05), '-')) AS [CTRC06],
a.CTDESC AS [CTDESC],
a.CTSEGN AS [CTSEGN]
FROM [PSA].[dbo].[SMFD35_GLDBFA_GLPCT] a WITH (NOLOCK);
我正在使用 SQL Server。
解决方案
有几种方法可以做到这一点,因为您的表中已经有了值,一种方法是从原始表中添加一个 id 字段并标记 CTRC (LevelNr) 对应于结果中的 CTACCT:
select A.CTACCT, max(B.CTRC01) AS CTRC01,
max(case when B.LevelNr = 1 then B.Description else null end) AS CTRC01_Description,
max(case when A.LevelNr >=2 then B.CTRC02 else null end) AS CTRC02,
max(case when A.LevelNr >=2 and B.LevelNr = 2 then B.Description else null end) AS CTRC02_Description,
max(case when A.LevelNr >=3 then B.CTRC03 else null end) AS CTRC03,
max(case when A.LevelNr >=3 and B.LevelNr = 3 then B.Description else null end) AS CTRC03_Description
from @MyResults A
inner join @MyResults B on A.id = B.id
group by A.[CTACCT], A.id, A.LevelNr
order by A.[CTACCT], A.id, A.LevelNr
结果:
CT_ACCT CTRC01 CTRC01_Description CTRC02 CTRC02_Description CTRC03 CTRC03_Description
001 001 Company NULL NULL NULL NULL
001-0000 001 Company 001-0000 Department NULL NULL
001-0000-0000 001 Company 001-0000 Department 001-0000-0000 Location
不过,这实际上应该是关于数据库设计的讨论。如果您有单独存储每个 CTRC 值的数据,那么 STRING_AGG() 和 PIVOT 等分组函数就会发挥作用。
假设您可以使用 UNION 查询使您的数据处于如下状态:
id RowNr CTAcct
1 1 001
1 2 0000
1 3 0000
2 1 002
2 2 0000
2 3 0000
然后,您可以将所有帐号和描述放在一起,如下所示(STRING_AGG 更好,但 FOR XML 将为您的版本解决问题):
select [CTACCT], id, RowNr, Description
from
(
select RowNr, id,
STUFF((SELECT '-' + [CTACCT]
from @CTACCTS A where A.[id] = T.[id] and A.[RowNr] <= T.[RowNr]
FOR XML PATH('')),1, 1,'') as [CTACCT]
from @CTACCTS T
) A left join @CTDESCRIPTIONS D ON A.[CTACCT] = D.[CTACCT]
结果:
CTACCT id RowNr Description
001 1 1 Company
001-0000 1 2 Department
001-0000-0000 1 3 Location
最后,您可以执行与上述类似的操作,将事物重新组合在一起。这可能看起来像是额外的工作,但具有避免冗余的优点。
当然,您也可以执行一系列更新语句,但通常不建议在 SQL Server 中使用基于非集合的例程。
推荐阅读
- javascript - JavaScript 将侦听器附加到表列以进行排序
- java - 将 S3ObjectInputStream 映射到输入流
- javascript - 将关联数组字符串转换为数组
- c++ - While 循环中的 C++ cin 输入验证
- asp.net-core - ASP.NET Core 声明未正确获取
- javascript - vue-msal 无法解析端点。请检查网络并重试。详细信息:函数 toString() { [本机代码] }
- javascript - 如何使用 javascript 在此代码中添加计时器?
- python - 无法从包含日期的数据框列中提取年份
- python - 如何绘制 pd.Series 并使用来自另一个数据源的每个点的颜色?
- reactjs - 如何以 formik 形式从 DOM 中删除空的错误 div?