我正在尝试组合两个csv字段,消除重复,排序并将其存储在新字段中。
我能够做到这一点。但是,我遇到的情况是值类似于abc和abc *。我需要用abc *保留一个并删除另一个。 这可以在没有逐行处理的情况下实现吗?
这就是我所拥有的。
CREATE TABLE csv_test
(
Col1 VARCHAR(100),
Col2 VARCHAR(100),
Col3 VARCHAR(500)
);
INSERT dbo.csv_test (Col1, Col2)
VALUES ('xyz,def,abc', 'abc*,tuv,def,xyz*,abc'), ('qwe,bca,a23', 'qwe,bca,a23*,abc')
--It is assumed that there are no spaces around commas
SELECT Col1, Col2, Col1 + ',' + Col2 AS Combined_NonUnique_Unsorted,
STUFF((
SELECT ',' + Item
FROM (SELECT DISTINCT Item FROM dbo.DelimitedSplit8K(Col1 + ',' + Col2,',')) t
ORDER BY Item
FOR XML PATH('')
),1,1,'') Combined_Unique_Sorted
, ExpectedResult = 'Keep the one with * and make it unique'
FROM dbo.csv_test;
--Expected Results; if there are values like abc and abc* ; I need to keep abc* and remove abc ;
--How can I achieve this without looping or using temp tables?
abc,abc*,def,tuv,xyz,xyz* -> abc*,def,tuv,xyz*
a23,a23*,abc,bca,qwe -> a23*,abc,bca,qwe
答案 0 :(得分:1)
好吧,既然你同意将数据库规范化是正确的事情,我决定尝试为你提出一个解决方案。
我最终得到了一个非常繁琐的解决方案,涉及4个(!)公用表表达式 - 繁琐,但它的工作原理。
第一个 cte是添加表格中缺少的行标识符 - 我已经使用了ROW_NUMBER() OVER(ORDER BY Col1, Col2)
。
second cte是通过组合两个csv列来获取一组唯一值。请注意,这还没有处理*
部分
第三个 cte正在处理*
问题
最后,第四个 cte将所有独特的项目放回到单个csv中。 (我可以在第三个cte中完成它,但我想让每个cte负责解决方案的一个部分 - 它更具可读性。)
现在剩下的就是用第四个cte的Col3
来更新第一个cte的Combined_Unique_Sorted
:
;WITH cte1 as
(
SELECT Col1,
Col2,
Col3,
ROW_NUMBER() OVER(ORDER BY Col1, Col2) As rn
FROM dbo.csv_test
), cte2 as
(
SELECT rn, Item
FROM cte1
CROSS APPLY
(
SELECT DISTINCT Item
FROM dbo.DelimitedSplit8K(Col1 +','+ Col2, ',')
) x
), cte3 AS
(
SELECT rn, Item
FROM cte2 t0
WHERE NOT EXISTS
(
SELECT 1
FROM cte2 t1
WHERE t0.Item + '*' = t1.Item
AND t0.rn = t1.rn
)
), cte4 AS
(
SELECT rn,
STUFF
((
SELECT ',' + Item
FROM cte3 t1
WHERE t1.rn = t0.rn
ORDER BY Item
FOR XML PATH('')
), 1, 1, '') Combined_Unique_Sorted
FROM cte3 t0
)
UPDATE t0
SET Col3 = Combined_Unique_Sorted
FROM cte1 t0
INNER JOIN cte4 t1 ON t0.rn = t1.rn
验证结果:
SELECT *
FROM csv_test
ORDER BY Col1, Col2
结果:
Col1 Col2 Col3
qwe,bca,a23 qwe,bca,a23*,abc a23*,abc,bca,qwe
xyz,def,abc abc*,tuv,def,xyz*,abc abc*,def,tuv,xyz*