2017-09-02 6 views
3

私は、乗客の識別情報、出発地と到着先の航空会社のテーブルを持っています。2つの列に渡って同一のペアを識別する

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

私は何をしたいの結果は次のようになりますので、そこに戻ってちょうど1つのルートをした乗客を見つけることです

なぜこの乗客ID:

1つの帰り旅行と1つのノンリターンがあるので、いいえ
2 - YESちょうど1対
3があるので - ( - 第VIIなく、第VII - バドバド)
4 - 復路がないので、NO 1対がまだあるので、YESであるが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つの列を比較する方法がわかりません。

答えて

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

2つの異なるペア(1つは往復で、1つは往復ではありますが)のいずれかに帰着トリップがないためID 5を削除するため、ID 1を消去するため、データと説明があいまいです帰りの便があればID 5が含まれるが、ハノイからバンコクの脚があればID 1は含まれないことを示す脚のフライト。

のIDは、のペアから送信されます(ただし、複数のトリップはOKです)。これは明らかではない。

これは、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) 

最初のクエリは、少なくとも1つの「往復」を有するIDのみを選択するので、ID3(および同様のもの)を除去する。 2番目のクエリは、完全ではないまたは異なるトリップを持つすべてのIDを見つけ出し、それらを削除します。さらに別の方法

+0

はい、あなたは正しいですが、そのために申し訳ありませんが、私は質問を更新します。 私が解決する課題は、複数のトリップであっても、単一のfrom/toのペアを持つ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; 
関連する問題