【问题标题】:How to find unique pairs from two columns in SQL?如何从 SQL 中的两列中查找唯一对?
【发布时间】:2020-07-21 18:36:24
【问题描述】:

我有一个表“Dummy”,其中包含“col1 和 col2”列。

我如何从 (col1,col2) 中找到唯一的对。例如在上表中,我如何将 (a,b) 或 (b,a) 仅作为我的输出,而不是 (a,b) 和 (b,a)。

select
    distinct
    col1
    col2
from
    dummy
where
    dummy.col1 < dummy.col2
group by
    col1,
    col2;

上面的查询是错误的,因为它错过了 (d,c) 对。

【问题讨论】:

  • 我想你想要WHERE col1 &lt;&gt; col2,而不是WHERE col1 &lt; col2
  • 您需要获取现有的d,c 还是c,d 也可以?
  • @Dai 在这种情况下你会得到a, dd, a
  • 嗨。这是一个常见问题解答。 你可能只是用谷歌搜索你的标题。总是用谷歌搜索你的问题/问题/目标/desiderata的许多清晰、简洁、特定的版本/变体/短语,有和没有你的特定字符串/名称/代码和'stackoverflow ' 并从许多问题中阅读许多答案,这应该会为您进一步的谷歌搜索提供信息。如果在应用所学知识并重复此操作后找不到答案,请提出问题。使用最常见的高效关键字作为标签。使用最佳搜索作为标题。

标签: mysql sql database


【解决方案1】:

我宁愿使用 concat 和 group by

SELECT 
col1,col2 
FROM 
tbl
GROUP BY CONCAT(LEAST(col1, col2), 
              GREATEST(col1, col2))

或者简单

SELECT 
    col1,col2 
    FROM 
    tbl
group by LEAST(col1, col2),GREATEST(col1, col2)

【讨论】:

  • 当然这只适用于 MySQL,在其他 DBMS 或 ONLY_FULL_GROUP_BY 启用时会失败。
【解决方案2】:

如果您不关心现有组合是否以正确的顺序返回,例如a,b 也可能返回为b,a

SELECT DISTINCT
  CASE WHEN col1 > col2 THEN col2 ELSE col1 end, -- similar to LEAST
  CASE WHEN col1 < col2 THEN col2 ELSE col1 end  -- similar to GREATEST
FROM dummy
;

但如果你必须返回一个现有的行,那就更复杂了:

SELECT t1.*
FROM dummy AS t1 LEFT JOIN dummy AS t2
ON  t1.col1 = t2.col2
AND t1.col2 = t2.col1
AND t1.col1 > t2.col1
WHERE t2.col1 IS NULL
;

SELECT col1,col2
FROM dummy AS t1
WHERE NOT EXISTS(
  SELECT * FROM dummy t2
  WHERE t1.col1 = t2.col2
    AND t1.col2 = t2.col1
    AND t1.col1 > t2.col1
);

【讨论】:

    【解决方案3】:

    使用leastgreatest

    select least(col1,col2),greatest(col1,col2) 
    from tbl
    group by least(col1,col2),greatest(col1,col2) 
    

    但是如果只有一对 (x,y) 或 (y,x) 存在,这可能会返回不在表中的行。

    为避免这种情况,请使用

    select least(col1,col2) as col1,greatest(col1,col2) as col2
    from tbl
    group by least(col1,col2),greatest(col1,col2) 
    having count(*)>1
    union all
    select col1,col2 
    from tbl
    where (least(col1,col2),greatest(col1,col2)) in (select least(col1,col2) as col1,greatest(col1,col2) as col2
                                                     from tbl
                                                     group by least(col1,col2),greatest(col1,col2) 
                                                     having count(*)=1
                                                    )    
    

    【讨论】:

      【解决方案4】:
      SELECT
          x,
          y
      FROM
      (
      
          SELECT
              DISTINCT
              col1 AS x,
              col2 AS y
          FROM
              dummy
          WHERE
              col1 <> col2
      
          UNION
      
          SELECT
              DISTINCT
              col1 AS y,
              col2 AS x
          FROM
              dummy
          WHERE
              col1 <> col2
      )
      

      【讨论】:

      • 为什么在 UNION 不同的情况下使用外部 Select 以及为什么有两个 DISTINCT?
      猜你喜欢
      • 2017-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-22
      • 2014-11-09
      • 1970-01-01
      相关资源
      最近更新 更多