通过连接字段加入(CSV 格式)
Join by concatenated field (in CSV format)
更新: 我完全知道这是一个糟糕的 RDBMS 实践,但问题不是问它是否是以及我如何重新培训创建这个的 DBA建筑学。问题是我如何解决手头的情况。我感谢社区的帮助,并且必须承认这确实是一个有趣的问题。
在 SQL Server 2017 中,我有一个包含代码的查找 table 和一个带有 CSV 格式代码的交易 table:
CREATE TABLE #t(cd VARCHAR(100))
CREATE TABLE #cd (id INT, cd VARCHAR (1000))
INSERT INTO #t SELECT 'c1'
INSERT INTO #t SELECT 'c1,c2'
INSERT INTO #t SELECT 'c1,c2,c3'
INSERT INTO #cd SELECT 10, 'c1'
INSERT INTO #cd SELECT 20, 'c2'
INSERT INTO #cd SELECT 30, 'c3'
所以,查找是
id cd
10 c1
10 c1
20 c2
30 c3
并且,交易 table 有:
cd
c1
c1,c2
c1,c2,c3
我需要将代码替换为其各自的 ID,同时将这些代码保留为 CSV 格式。
我想避开游标,因为它太慢了。有没有一种方法可以有效地解析代码、执行 JOIN 和重新组合 ID?我想 COALESCE 可能有用,但需要帮助来应用它。也许,在 t-SQL 中已经有一个函数可以执行这种类型的查找。
输出需要到交易中的另一列table:
id
10
10,20
10,20,30
您可以先将逗号删除到列表中,然后加入并获取代码的正确 ID,然后用逗号将它们添加回去。我预先使用 row_number 来获得一个独特的东西,以便在我的查询中重新加入。
CREATE TABLE #t(cd VARCHAR(100))
CREATE TABLE #cd (id INT, cd VARCHAR (1000))
INSERT INTO #t SELECT 'c1'
INSERT INTO #t SELECT 'c1,c2'
INSERT INTO #t SELECT 'c1,c2,c3'
INSERT INTO #cd SELECT 10, 'c1'
INSERT INTO #cd SELECT 20, 'c2'
INSERT INTO #cd SELECT 30, 'c3'
; WITH X AS
(
SELECT
C.id,P1.rn
FROM
(
SELECT *, row_number() over( order by (select 1)) rn,
cast('<X>'+replace(P.cd,',','</X><X>')+'</X>' as XML) AS xmlitems FROM #t P
)P1
CROSS APPLY
(
SELECT fdata.D.value('.','varchar(100)') AS splitdata
FROM P1.xmlitems.nodes('X') AS fdata(D)) O
LEFT JOIN #cd C
ON C.cd= LTRIM(RTRIM(O.splitdata ))
)
SELECT
rn,
id= STUFF((
SELECT ',' + cast(id as varchar(100)) FROM X AS x2
WHERE x2.rn = x.rn
ORDER BY rn FOR XML PATH,
TYPE).value(N'.[1]',N'varchar(max)'), 1, 1, '')
FROM
X
GROUP BY rn
注意: 使用 SQL server 2017 您还可以使用 SPLIT_STRING() 函数
和 STRING_AGG() 函数
SQL 服务器 2017 代码:
select
id=STRING_AGG(id,',')
from
(
select V=value, rn
from
(
select
rn=row_number() over( order by (select 1)),
cd
from #T
)T
cross apply STRING_SPLIT(cd, ',')
) T
left join #cd C
on cd= v
group by rn
更新: 我完全知道这是一个糟糕的 RDBMS 实践,但问题不是问它是否是以及我如何重新培训创建这个的 DBA建筑学。问题是我如何解决手头的情况。我感谢社区的帮助,并且必须承认这确实是一个有趣的问题。
在 SQL Server 2017 中,我有一个包含代码的查找 table 和一个带有 CSV 格式代码的交易 table:
CREATE TABLE #t(cd VARCHAR(100))
CREATE TABLE #cd (id INT, cd VARCHAR (1000))
INSERT INTO #t SELECT 'c1'
INSERT INTO #t SELECT 'c1,c2'
INSERT INTO #t SELECT 'c1,c2,c3'
INSERT INTO #cd SELECT 10, 'c1'
INSERT INTO #cd SELECT 20, 'c2'
INSERT INTO #cd SELECT 30, 'c3'
所以,查找是
id cd
10 c1
10 c1
20 c2
30 c3
并且,交易 table 有:
cd
c1
c1,c2
c1,c2,c3
我需要将代码替换为其各自的 ID,同时将这些代码保留为 CSV 格式。
我想避开游标,因为它太慢了。有没有一种方法可以有效地解析代码、执行 JOIN 和重新组合 ID?我想 COALESCE 可能有用,但需要帮助来应用它。也许,在 t-SQL 中已经有一个函数可以执行这种类型的查找。
输出需要到交易中的另一列table:
id
10
10,20
10,20,30
您可以先将逗号删除到列表中,然后加入并获取代码的正确 ID,然后用逗号将它们添加回去。我预先使用 row_number 来获得一个独特的东西,以便在我的查询中重新加入。
CREATE TABLE #t(cd VARCHAR(100))
CREATE TABLE #cd (id INT, cd VARCHAR (1000))
INSERT INTO #t SELECT 'c1'
INSERT INTO #t SELECT 'c1,c2'
INSERT INTO #t SELECT 'c1,c2,c3'
INSERT INTO #cd SELECT 10, 'c1'
INSERT INTO #cd SELECT 20, 'c2'
INSERT INTO #cd SELECT 30, 'c3'
; WITH X AS
(
SELECT
C.id,P1.rn
FROM
(
SELECT *, row_number() over( order by (select 1)) rn,
cast('<X>'+replace(P.cd,',','</X><X>')+'</X>' as XML) AS xmlitems FROM #t P
)P1
CROSS APPLY
(
SELECT fdata.D.value('.','varchar(100)') AS splitdata
FROM P1.xmlitems.nodes('X') AS fdata(D)) O
LEFT JOIN #cd C
ON C.cd= LTRIM(RTRIM(O.splitdata ))
)
SELECT
rn,
id= STUFF((
SELECT ',' + cast(id as varchar(100)) FROM X AS x2
WHERE x2.rn = x.rn
ORDER BY rn FOR XML PATH,
TYPE).value(N'.[1]',N'varchar(max)'), 1, 1, '')
FROM
X
GROUP BY rn
注意: 使用 SQL server 2017 您还可以使用 SPLIT_STRING() 函数 和 STRING_AGG() 函数
SQL 服务器 2017 代码:
select
id=STRING_AGG(id,',')
from
(
select V=value, rn
from
(
select
rn=row_number() over( order by (select 1)),
cd
from #T
)T
cross apply STRING_SPLIT(cd, ',')
) T
left join #cd C
on cd= v
group by rn