2

如何选择 2 行的不同组合。

例如。给出下表

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

我要选择

Col1 Col2
A      B
A      C
C      B

请注意,仅使用 distinct 关键字将不起作用,因为它将包括最后一行 B,A。

我不希望返回最后一行,因为反向组合 (A,B) 已经在集合中。

4

4 回答 4

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)
于 2013-05-14T23:53:47.413 回答
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

现在查询:

查询选项 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

注意:两个查询的结果略有不同,但两个查询都返回相同且正确的结果集

于 2016-03-23T13:31:21.517 回答
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);
于 2013-05-15T00:00:17.300 回答
0

我不认为你可以用 SQL 做到这一点。虽然 SQL 针对处理数据集进行了优化,但这与数学集不同,无论顺序如何,一个集合都等于另一个集合,因为它包含相同的项目。

我会在你的程序中实现或使用一个正确的 Set 类,它确实理解数学集合逻辑,然后可以用来从 SQL 查询中排除结果。

于 2013-05-14T23:51:51.113 回答