【问题标题】:SQL to get distinct record for a combination of two column (Irrespective of order)SQL 为两列的组合获取不同的记录(不考虑顺序)
【发布时间】:2016-02-25 17:06:27
【问题描述】:

考虑下面的表结构和数据

CREATE TABLE Distance(
      source VARCHAR(20),
      destination VARCHAR(20),
      distance INTEGER
      );

Select * from Distance;

source     destination  distance
=======    ===========  ======
Chennai    Mumbai       500
Mumbai     Chennai      500
Mumbai     Bangalore    500
Bangalore  Mumbai       500
Goa        Mumbai       100
Mumbai     Goa          100
Kolkata    Goa          1000

如果重复,我需要输出有2个城市的单一记录,即以下2个中的任何一个记录都可以。

Chennai    Mumbai       500
Mumbai     Chennai      500

Expected o/p:
source     destination  distance
=======    ===========  ======
Chennai    Mumbai       500
Mumbai     Bangalore    500
Goa        Mumbai       100
Kolkata    Goa          1000

【问题讨论】:

    标签: mysql sql-server oracle10g teradata


    【解决方案1】:

    这是使用least()greatest() 的一种方法:

    select least(source, destination), greatest(source, destination), max(distance)
    from distance
    group by least(source, destination), greatest(source, destination);
    

    这样做的缺点是您可能会返回不在表中的行。例如,如果您有一行包含“Mumbai/Chennai/500”,那么此查询将返回“Chennai/Mumbai/500”——而该行不在原始表中。

    所以,另一种方法是:

    select source, destination, distance
    from distance
    where source < destination
    union all
    select destination, source, distance
    from distance d
    where source > destination and
          not exists (select 1
                      from distance d2
                      where d2.source = d.destination and d2.destination = d.source
                     );
    

    此版本也与 ANSI 兼容,应该适用于所有数据库。

    【讨论】:

    • @Strawberry 。 . .我添加了更多解释。
    • 这是标准 SQL,但不保留列的顺序 :)
    【解决方案2】:

    如果您需要保留可能使用的列顺序

    SELECT *
    FROM Distance t1
    WHERE NOT EXISTS
     (
       SELECT * FROM Distance t2
       WHERE t1.destination = t2.source
         AND t1.source = t2.destination
         AND t1.destination > t2.destination
     );
    

    当每个source/combination 存在多行时,您必须添加DISTINCTGROUP BY

    【讨论】:

      【解决方案3】:
      SELECT DISTINCT LEAST(source,destination) a
                    , GREATEST(source,destination) b
                    , distance 
                 FROM distance;
      

      【讨论】:

      • 我喜欢这个解决方案,但它不是 SQL 标准。它可以在 MySQL、PostgreSQL 和 Oracle 上运行,但不能在 SQL Server 上运行。见这里:stackoverflow.com/questions/3794451/…
      • 嗯,当时情况不同
      【解决方案4】:
      select   
      (case when source>destination then source else destination end) as src,
      (case when source<destination then source else destination end) as dstn,
      distance from distance
      

      【讨论】:

      • 您正在添加一个问题的答案,其中包含 5 年前发布的多个投票的答案。您应该添加一些文字来解释为什么 5 年后,您的答案现在才出现。这是 5 年前不存在的新语法吗?你的答案比其他人好吗?如果这两个问题的答案都是“否”,那么您的答案可能只会让其他发现此问题并寻求指导的人感到困惑,因此是不合适的。
      【解决方案5】:

      下面的逻辑似乎更容易理解,并且做同样的工作。

          select a.source,a.destination,a.distance as distance  from
          distance a join distance b on a.destination = b.source and b.destination = a.source
          and a.source < b.source
          union all
          select a.source,a.destination,a.distance from distance a  left join distance b 
          on a.destination = b.source and b.destination = a.source
          where b.source is NULL ;
      

      【讨论】:

        猜你喜欢
        • 2016-09-22
        • 1970-01-01
        • 1970-01-01
        • 2012-02-20
        • 1970-01-01
        • 1970-01-01
        • 2016-12-25
        • 1970-01-01
        • 2020-06-08
        相关资源
        最近更新 更多