2013-05-14 138 views
2

如何選擇2行的不同組合。如何在sql中選擇不同組合的2行

例如。如下表

Col1 Col2 
A  B 
A  B 
A  C 
C  B 
B  A 

我想選擇只是用不同的關鍵字是行不通的,因爲它會包括最後一排B,A

Col1 Col2 
A  B 
A  C 
C  B 

注意。

我不希望最後一行被返回,因爲反向組合(A,B)已經在集合中。

+0

如果你有A,B和B,A,你想看哪一個? – Brandon

+0

我有一種感覺,這是SQL優化的一組數據和數組之間的混淆,如果它們包含相同的項目(無論順序如何),那麼這兩個數據集可以相等。 –

+0

@Brandon,老實說我不在乎,只要他們中的一個出現。 –

回答

0

我不認爲你可以用SQL來做到這一點;雖然SQL針對處理數據集進行了優化,但這與不考慮順序的數學集不同,一個集合等於另一個集合,因爲它包含相同的項目。

我會在你的程序中實現或使用一個合適的Set類,它理解數學集邏輯,然後可以用來排除SQL查詢的結果。

+0

只是爲了澄清;是的,你*可以*明顯在SQL中做到這一點;我不相信你應該在SQL中這樣做。 –

1
SELECT t1.col1,t1.col2 FROM table t1 WHERE col2 not in (SELECT t2.col1 FROM table t2 WHERE t2.col2 = t1.col1) GROUP BY t1.col1,t1.col2 

SELECT DISTINCT t1.col1, t1.col2 FROM table t1 WHERE col2 not in (SELECT t2.col1 FROM table t2 WHERE t2.col2 = t1.col1) 
0

我驗證了以下工作。如果你想讓它對付更多的集合,那麼你會包含額外的NOT EXISTS語句組合。

WITH BaseData 
AS 
    (SELECT Column1, Column2 
    FROM (VALUES 
     ('A', 'B'), ('A', 'B'), ('A', 'C'), ('C', 'B'), ('B', 'A')) val (Column1, Column2)) 
SELECT Column1, Column2 
FROM 
    (SELECT Column1, Column2 
    FROM BaseData 
    GROUP BY Column1, Column2) sub1 
WHERE NOT EXISTS 
    (SELECT 1 
    FROM BaseData 
    WHERE Column1 = Column2 
    AND Column2 = Column1); 
1

有趣的是,上述解決方案都沒有爲問題提供正確的答案。

。由此可以使用兩個可能的答案:

首先,生成「基表」(注:我已經添加了一些額外的測試用例):

Declare @Test table (Column1 varchar(10), Column2 varchar(10)) 

Insert into @Test 
VALUES ('A','B'),('A','B'),('A','C'),('C','B'),('B','A'),('D', 'A'), ('d','e'), ('a', 'b'), ('C','A') 

select * from @Test 

這導致:

Column1  Column2 
A   B 
A   B 
A   C 
C   B 
B   A 
D   A 
d   e 
a   b 
C   A 

現在的疑問:

查詢的Opti 1:

;WITH numb as (Select *, Num = ROW_NUMBER() Over(Order by Column1,Column2) from @Test) 
, Num2 as (Select T.*, n.Num from @Test t 
     Inner Join numb n on (t.Column1 = n.Column1 and t.Column2 = n.Column2) or (t.Column1 = n.Column2 and t.Column2 = n.Column1)) 
,rankk as (select *, rnk = rank() Over(partition by num order by Column1) from Num2) 

select DISTINCT Column1, Column2 from rankk where rnk = 1 

結果選項1:

Column1  Column2 
a   b 
A   C 
C   B 
D   A 
d   e 

查詢選項2:

;WITH source AS (SELECT Column1, Column2, 
     Test = (CASE WHEN Column1 < Column2 THEN Column1 ELSE Column2 END 
      + CASE WHEN Column1 > Column2 THEN Column1 ELSE Column2 END) 
     FROM (
      SELECT Distinct Column1, Column2 
      FROM @Test AS bd 
    ) AS sub1 
) 
SELECT Column1 = MIN(s.Column1), Column2 = MAX(s.Column2) 
FROM source AS s 
GROUP BY s.Test; 

結果選項2:

Column1  Column2 
A   B 
A   C 
D   A 
C   B 
d   e 

注: 2個查詢的結果略有不同,但兩者查詢返回相同的,正確的結果集