1

我需要一个查询,它返回 colA 与 colB 配对的所有行,但将相反方向的相同值视为重复项并被删除。

解释此查询的最佳方式是举例:

colA | colB
-----------
abc  | def
def  | abc
asdf | 1234
1234 | asdf
other| row
1234 | test

SQL 魔法

colA | colB
-----------
abc  | def
asdf | 1234
other| row
1234 | test

它删除了在另一个方向上“重复”的行。

4

3 回答 3

2

如果您更喜欢“干净”的 SQL 解决方案(没有least()or greatest()),这也可以完成您的工作:

select colA, colB from your_table
where colA > colB 
  or (colB, colA) not in (select colA, colB from your_table)

SQL小提琴

于 2013-05-02T16:45:07.223 回答
1

尝试这个:

select t3.colA,t3.colB
from table_name t3
where (t3.colA,t3.colB)
not in
(select greatest(t1.colA, t1.colB), least(t1.cola, t1.colB)
from table_name t1 , table_name t2
where t1.colB=t2.colA and t1.colA=t2.colB
group by greatest(t1.colA,t1.colB), least(t1.cola, t1.colB))

SQL 小提琴

于 2013-05-02T16:43:33.750 回答
1

我的 SQL 具有函数least()greatest(). 返回唯一对的查询:

select least(colA, colB), greatest(cola, colB)
from t
group by least(colA, colB), greatest(cola, colB)

但是,这可能会重新排列非重复行的值。例如,如果一行是 (z, a),那么这里的结果就是 (a, z)。

为了解决这个问题,我们需要找到正确的值。这个想法是计算该对的每个版本出现的次数。如果它出现两次,那么选择哪个似乎是任意的。如果有一次,那么我们需要取出原始行。

这是执行此操作的版本:

select (case when cnt = 1 then colA else l end) as ColA,
       (case when cnt = 1 then colB else g end) as ColB
from (select least(colA, colB) as l, greatest(cola, colB) as g,
             count(distinct colA) as cnt, min(colA) as colA, min(colB) as colB
      from t
       group by least(colA, colB), greatest(cola, colB)
     ) t

这是在做什么?原始查询找到唯一对。在子查询中,它计算该对的每个版本出现在数据中的次数,并将colAcolB作为列包含在内。

然后,外部查询为每个已识别的对选择要显示的内容。如果计数是 1——只有一个版本——那么min(colA)是 ColA,然后min(colB)是 colB。所以,使用那些。否则,它会任意选择 ColA < ColB 的对。

于 2013-05-02T16:11:34.050 回答