SQL 获取两列组合的不同记录(不考虑顺序)

问题描述 投票:0回答:6

考虑下面的表结构和数据

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
6个回答
4
投票

这是一种使用

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,并且应该适用于所有数据库。


4
投票

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

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
存在多行时,您必须添加
DISTINCT
GROUP BY


1
投票
SELECT DISTINCT LEAST(source,destination) a
              , GREATEST(source,destination) b
              , distance 
           FROM distance;

0
投票
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

0
投票

下面的逻辑看起来更容易理解,并且做同样的工作。

    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 ;

0
投票

cte 为 ( 选择 *,CASE WHEN 来源

cte_rn 为 ( select *,ROW_NUMBER () over(按梳排序按梳分区) as rn 来自 cte)

选择出发地、目的地、距离 cte_rn 其中 rn=1 按来源排序

© www.soinside.com 2019 - 2024. All rights reserved.