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对,即使有多个行程。我试图简化这个问题的数据,但忘记了这一点。