在逗号分隔的值中查找包含相同值的行

时间:2019-01-30 11:55:42

标签: sql sql-server csv sql-server-2014

我有一个varchar列,该列由另一个我无法控制的进程填充,其中填充了逗号分隔的值。

现在,我需要查找同一列另一行中存在该列一部分的所有行

示例

declare @table table (value varchar(50))
insert into @table values ('NB,BD,FR'), ('BD,GK'), ('SL,SR')

select * from @table

因此表包含

value   
-----   
NB,BD,FR    
BD,GK   
SL,SR   

从上面的例子中我想得到

value   
-----   
NB,BD,FR    
BD,GK   

因为两行中都有一个值(在这种情况下为BD,但可以是任何值)

这可以在sql中完成吗?

2 个答案:

答案 0 :(得分:3)

您可以使用笨拙的XML操作将逗号分隔的值转换为行:

DECLARE @table TABLE (value VARCHAR(50));
INSERT INTO @table VALUES
('NB,BD,FR'),
('BD,GK'),
('SL,SR');

WITH cte AS (
    SELECT value, node.value('.', 'varchar(10)') AS substr
    FROM @table
    CROSS APPLY (SELECT CAST('<x>' + REPLACE(value, ',', '</x>,<x>') + '</x>' AS XML)) AS x(doc)
    CROSS APPLY doc.nodes('/x') AS n(node)
)
-- use your favorite technique to find the duplicate
SELECT value
FROM cte AS m
WHERE EXISTS (
    SELECT 1
    FROM cte AS x
    WHERE value <> m.value AND substr = m.substr
)

CAST(... AS XML)部分假定您的数据不包含在XML中具有特殊含义的字符。 nodes方法会将一行转换为很多行,其余的将很简单。

答案 1 :(得分:0)

这是错误的数据结构。不要将值存储在字符串中!

declare @table table (id int, value varchar(50));
insert into @table
    values (1, 'NB'), (1, 'BD'), (1, 'FR'),
           (2, 'BD'), (2, 'GK'),
           (3, 'SL'), (3, 'SR');

然后,您可以使用窗口功能获得所需的内容:

 select id, value
 from (select t.*, max(cnt) over (partition by id) as max_cnt
       from (select t.*, count(*) over (partition by value) as cnt
             from @table t
            ) t
      ) t
 where max_cnt >= 2