2011-08-16 11 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以獲得更受歡迎的結構。需要考慮的事項包括:確切的劃分或剩餘部分;如何處理空的除數。