2017-09-02 46 views
3

我有一个乘客识别器,他们的出发和到达目的地的航空公司的表。跨两列识别相同的对

+-------------+-----------+----------+ 
| 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 | 
+-------------+ 

为什么这个乘客ID:

1 - 没有,因为有1个回程和1个回报
2 - YES,因为仅存在1对
3 - NO,因为没有一个回程(芽 - VIL但不VIL - 芽)
4 - YES,因为还有1对虽然超过2个行程
5 - NO,因为没有回程这些对

我想是这样的:

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

但是,这也包括完全diferent目的地(ID 5)结果集。我无法弄清楚如何将两列进行分组。

回答

2

像往常一样使用SQL有几种方式来获得不同的查询相同的结果......我会发布我的。

这里的工作SQLfiddle:http://sqlfiddle.com/#!9/385d3/1

数据建立

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 
)) 

的最内层查询(FROM TRAVEL b)找到所有回程相对于中间查询(FROM TRAVEL a)。

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

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

1
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 
) 
0

你的数据和解释是不明确的,因为你消除了ID 1,因为它有两个不同的对(尽管一个是往返行程,一个不是),但是你消除了ID 5,因为没有返回行程如果包含返程航班,则表示包含ID 5,但如果包含河内至曼谷航段,则不包含ID 1。

您是否只包含ID为单个起/至成对(但多次旅行都可以)?这不清楚。

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

SELECT DISTINCT(t1.id) FROM Travel t1 JOIN Travel t2 ON (t1.id=t2.id AND 
t1.town_from=t2.town_to AND t1.town_from<>t2.town_from AND 
t1.town_to<>t2.town_to) 
EXCEPT 
SELECT DISTINCT(t1.id) FROM Travel t1 JOIN Travel t2 ON (t1.id=t2.id AND 
t1.town_from<>t2.town_to AND t1.town_from<>t2.town_from AND 
t1.town_to<>t2.town_to) 

的第一个查询消除了ID 3(等等),因为它只选择至少有一次'往返'的ID。第二个查询查找所有具有非完整或不同行程的ID并将其消除。

+0

是的,你说得对,对不起,我会虽然已经回答了更新的问题。 我解决的任务只需要一个从/来的ID即使是多次出行也是如此。我试图简化这个问题的数据,并忘记了这一点。 – Musisak

0

还有一种方法:

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 

http://sqlfiddle.com/#!6/6ed3a/4

0
WITH CTE AS 
(
select distinct trv1.PassengerID, 
trv1.town_from AS a, 
trv1.town_to AS b, 
trv2.town_from AS c, 
trv2.town_to AS d 
FROM travel trv1 
LEFT JOIN travel trv2 ON trv1.PassengerID=trv2.PassengerID 
AND trv1.town_from=trv2.town_to 
AND trv1.town_to=trv2.town_from 
ORDER BY trv1.PassengerID, trv1.town_from 
), 

SCTE AS 
(
SELECT *, row_number() over(partition by CTE.PassengerID) AS count 
FROM CTE 
), 

SSCTE AS 
(
SELECT *, sum(SCTE.count) over(partition by SCTE.PassengerID) AS sum 
FROM SCTE 
) 

SELECT 
SSCTE.PassengerID, 
SSCTE.a, 
SSCTE.b 
from SSCTE 
WHERE SSCTE.sum = 3 
ORDER BY SSCTE.PassengerID;