Sql 跨两列标识相同的对

Sql 跨两列标识相同的对,sql,database,Sql,Database,我有一张航空公司的桌子,上面有乘客身份证、出发地点和到达地点 +-------------+-----------+----------+ | PassengerID | Town_from | Town_to | +-------------+-----------+----------+ | 1 | London | Valetta | | 1 | Valetta | London | | 1 | Bangkok

我有一张航空公司的桌子,上面有乘客身份证、出发地点和到达地点

+-------------+-----------+----------+
| PassengerID | Town_from | Town_to  |
+-------------+-----------+----------+
|           1 | London    | Valetta  |
|           1 | Valetta   | London   |
|           1 | Bangkok   | Hanoi    |
|           2 | Prague    | Vienna   |
|           2 | Vienna    | Prague   |
|           3 | Budapest  | Vilnius  |
|           4 | Moscow    | Helsinki |
|           4 | Helsinki  | Moscow   |
|           4 | Moscow    | Helsinki |
|           5 | Lyon      | Paris    |
|           5 | New York  | Toronto  |
+-------------+-----------+---------+
我想做的是找到只走一条路线往返的乘客,结果如下:

+-------------+-----------+----------+
| PassengerID | Town_from | Town_to  |
+-------------+-----------+----------+
|           2 | Prague    | Vienna   |
|           2 | Vienna    | Prague   |
|           4 | Moscow    | Helsinki |
|           4 | Helsinki  | Moscow   |
|           4 | Moscow    | Helsinki |
+-------------+-----------+---------+
+-------------+
| PassengerID |
+-------------+
|           2 |
|           4 |
+-------------+
或者像这样:

+-------------+-----------+----------+
| PassengerID | Town_from | Town_to  |
+-------------+-----------+----------+
|           2 | Prague    | Vienna   |
|           2 | Vienna    | Prague   |
|           4 | Moscow    | Helsinki |
|           4 | Helsinki  | Moscow   |
|           4 | Moscow    | Helsinki |
+-------------+-----------+---------+
+-------------+
| PassengerID |
+-------------+
|           2 |
|           4 |
+-------------+
为什么这名乘客:

1-否,因为有1个回程和1个不回程
2-是,因为只有一对
3-不,因为没有回程(Bud-Vil但不是Vil-Bud)
4-是的,因为尽管有2次以上的行程,但仍有1对
5-没有,因为这些对没有回程

我试过这样的方法:

SELECT PassengerID FROM table
GROUP BY PassengerID
HAVING COUNT(DISTINCT town_from) = 2 AND COUNT(DISTINCT town_to) = 2

但这也包括和结果集完全不同的目的地(ID5)。我不知道如何在分组时比较两列。

与SQL一样,有几种方法可以通过不同的查询获得相同的结果。。。我会把我的寄出去

DECLARE @FlightData TABLE (
    PassengerID INT,
    Town_from NVARCHAR(500),
    Town_to NVARCHAR(500)
)
INSERT INTO @FlightData(PassengerID,Town_from,Town_to) SELECT 1,'London','Valetta'
INSERT INTO @FlightData(PassengerID,Town_from,Town_to) SELECT 1,'Valetta','London'
INSERT INTO @FlightData(PassengerID,Town_from,Town_to) SELECT 1,'Bangkok','Hanoi'
INSERT INTO @FlightData(PassengerID,Town_from,Town_to) SELECT 2,'Prague','Vienna'
INSERT INTO @FlightData(PassengerID,Town_from,Town_to) SELECT 2,'Vienna','Prague'
INSERT INTO @FlightData(PassengerID,Town_from,Town_to) SELECT 3,'Budapest','Vilnius'
INSERT INTO @FlightData(PassengerID,Town_from,Town_to) SELECT 4,'Moscow','Helsinki'
INSERT INTO @FlightData(PassengerID,Town_from,Town_to) SELECT 4,'Helsinki','Moscow'
INSERT INTO @FlightData(PassengerID,Town_from,Town_to) SELECT 4,'Moscow','Helsinki'
INSERT INTO @FlightData(PassengerID,Town_from,Town_to) SELECT 5,'Lyon','Paris'
INSERT INTO @FlightData(PassengerID,Town_from,Town_to) SELECT 5,'New York','Toronto'

SELECT *
FROM @FlightData
WHERE PassengerID NOT IN(
    SELECT
        fd1.PassengerID
    FROM @FlightData fd1
    LEFT JOIN @FlightData fd2 ON fd2.PassengerID=fd1.PassengerID
        AND fd2.Town_from=fd1.Town_to
        AND fd2.Town_to=fd1.Town_from
    WHERE fd2.PassengerID IS NULL
)
下面是工作的SQLfiddle:

数据设置

create table travel(PassengerID  varchar(64),Town_from  varchar(64),Town_to varchar(64));

insert into travel values('1','London','Valetta');
insert into travel values('1','Valetta','London');
insert into travel values('1','Bangkok','Hanoi');
insert into travel values('2','Prague','Vienna');
insert into travel values('2','Vienna','Prague');
insert into travel values('3','Budapest','Vilnius');
insert into travel values('4','Moscow','Helsinki');
insert into travel values('4','Helsinki','Moscow');
insert into travel values('4','Moscow','Helsinki');
以及实际的查询

SELECT DISTINCT PassengerID
FROM TRAVEL
WHERE NOT EXISTS (
  SELECT PassengerID 
  FROM TRAVEL a
  WHERE TRAVEL.PassengerID = a.PassengerID AND NOT EXISTS
   (SELECT * 
    FROM TRAVEL b
    WHERE a.PassengerID = b.PassengerID 
    AND a.Town_from = b.Town_to
    AND a.Town_to = b.Town_from
))
最里面的查询(
来自行程b
)查找与中间查询(
来自行程a
)相关的所有往返行程

中间查询(
FROM TRAVEL a
)然后使用
NOT EXISTS
子句返回所有没有回程的旅行中的所有乘客


外部查询再次反转结果,从初始表中删除这些“不匹配”的行程。

您的数据和解释不明确,因为您删除了ID 1,因为它有两个不同的对(尽管一个是往返行程,另一个不是)但您取消了ID 5,因为单程航班都没有回程,这表明如果有回程航班,ID 5将包括在内,但如果有从河内到曼谷的航班,ID 1将不包括在内

您是否只包括具有单个“从/到”对的ID(但可以多次旅行)?这还不清楚

这是另一个例子,它将产生您想要的ID 2和4的结果(但是它不包括任何可能有多个完整和不同往返的ID,如果这是您的意图)

从行程t1选择不同的(t1.id)连接行程t2开(t1.id=t2.id)和
t1.town_from=t2.town_to和t1.town_fromt2.town_from和
t1.城镇总数2.城镇总数)
除了
从行程t1中选择不同的(t1.id)连接行程t2开(t1.id=t2.id),然后
t1.town_fromt2.town_to和t1.town_fromt2.town_fromt和
t1.城镇总数2.城镇总数)
第一个查询消除了ID 3(以及类似的内容),因为它只选择至少有一个“往返”的ID。第二个查询查找所有具有不完整或不同行程的ID,并将其删除。

另一种方法:

select distinct t1.PassengerID
from
    travel t1
    inner join travel t2
        on t1.PassengerID = t2.PassengerID AND
           t1.Town_from = t2.Town_to AND
           t1.Town_to = t2.Town_from
where
    (SELECT COUNT(*)
     FROM (SELECT DISTINCT PassengerID, Town_from, Town_to
           FROM travel t3
           WHERE t3.PassengerID = t1.PassengerID) temp
    ) = 2

是的,你是对的,很抱歉,我会更新问题,尽管它已经被回答了。我解决的任务只需要一个ID和一个from/to对,即使有多个行程。我试图简化这个问题的数据,但忘记了这一点。