2011-08-16 10 views
3

符合下表如何在SQL中查找多行匹配?

CREATE TABLE T1 (
    A varchar(2), 
    B varchar(2) 
); 

INSERT INTO T1 VALUES 
    ('aa', 'm'), ('aa', 'n'), 
    ('bb', 'n'), ('bb', 'o'), 
    ('cc', 'n'), ('cc', 'o'), 
    ('dd', 'c'), ('dd', 'a'), ('dd', 'r'), 
    ('ee', 'a'), ('ee', 'c'), ('ee', 'r') 

A | B 
----+---- 
aa | m 
aa | n 
bb | n 
bb | o 
cc | n 
cc | o 
dd | c 
dd | a 
dd | r 
ee | a 
ee | c 
ee | r 

如何选择和组的一场比赛中所有的coresponding值B.例如BB和CC的值组成一个组,因为它们都包含“n”和' O”。

那么结果将是

Group | A 
---------- 
1  | bb 
1  | cc 
2  | dd 
2  | ee 
+0

是否有组的最大尺寸(在你的例子中你有2,3) –

+0

没有最大尺寸 – Josh

回答

2

下面是一种方法:它首先计算匹配的“集合”,其中一个集合是两个匹配的两个A的集合。然后它计算“头”,或同组中最低的A。使用dense_rank,您可以对这些头进行编号,然后重新加入组列表以创建所有组成员的列表。

查询SE Data

; with groups as 
     (
     select distinct A 
     from @t 
     ) 
,  vals as 
     (
     select distinct B 
     from @t 
     ) 
,  sets as 
     (
     select g1.A as g1 
     ,  g2.A as g2 
     from groups g1 
     join groups g2 
     on  g1.A < g2.A 
     cross join 
       vals v 
     left join 
       @t v1 
     on  g1.A = v1.A 
       and v.B = v1.B 
     left join 
       @t v2 
     on  g2.A = v2.A 
       and v.B = v2.B 
     group by 
       g1.A 
     ,  g2.A 
     having count(case when isnull(v1.B,'') <> isnull(v2.B,'') then 1 end) = 0 
     ) 
,  heads as 
     (
     select s1.g1 
     ,  s1.g2 
     ,  head.head 
     from sets s1 
     cross apply 
       (
       select min(g1) as head 
       from sets s2 
       where s1.g2 = s2.g2 
       ) head 
     ) 
select distinct dense_rank() over (order by h.head) 
,  g.g 
from (
     select distinct head 
     from heads 
     ) h 
left join 
     (
     select g1 as g 
     ,  head 
     from heads 
     union all 
     select g2 
     ,  head 
     from heads 
     ) g 
on  h.head = g.head 
+0

谢谢,这工作,但表现不如我需要它。它会给我一个开始的好地方。 – Josh

1

SQL Server 2008中有EXCEPTINTERSECT功能,都可以使用。这不完全是你想要的格式,我不能说大数据集的性能,但也许它会给你一个起点。

SELECT DISTINCT 
    T1.A, 
    T2.A 
FROM 
    T1 AS T1 
INNER JOIN T1 AS T2 ON T2.A > T1.A 
WHERE 
    NOT EXISTS 
    (
    SELECT 
     B 
    FROM 
     T1 AS T3 
    WHERE 
     T3.A = T1.A 
    EXCEPT 
    SELECT 
     B 
    FROM 
     T1 AS T4 
    WHERE 
     T4.A = T2.A 
    ) AND 
    NOT EXISTS 
    (
    SELECT 
     B 
    FROM 
     T1 AS T3 
    WHERE 
     T3.A = T2.A 
    EXCEPT 
    SELECT 
     B 
    FROM 
     T1 AS T4 
    WHERE 
     T4.A = T1.A 
    ) 

根据你的数据,你也可以生成分隔符和字符串中的特定顺序一些连接的字符串,然后比较这些。

+0

+1串联的方法会更好,虽然设置的方法更有趣:) – Andomar

0

您需要的关系运算符是division,俗称为"the supplier who supplies all parts"

事实上,分部大约有八种风格,而SQL语言并没有直接实现它们。但是,它们都可以使用现有的SQL结构重新创建:请参阅this article以获得更受欢迎的结构。需要考虑的事项包括:确切的划分或剩余部分;如何处理空的除数。