我有以下表格:
create table passenger ( passenger_ID varchar ( 10 ) , passenger_name varchar ( 30 ) , passenger_city varchar ( 30 ) , primary key ( passenger_ID ) ) ;
create table flight ( flight_number varchar ( 10 ) , departure_airport varchar ( 10), arrival_airport varchar ( 10 ) , primary key ( flight_number ) );
create table seat (
flight_number varchar ( 10 ),
seat_number varchar ( 10 ),
primary key(flight_number, seat_number),
foreign key(flight_number) references flight);
create table reservation(
passenger_ID varchar ( 10 )
flight_number varchar ( 10 ) , seat_number varchar ( 10 ) ,
day date ,
fare numeric(8,2),
primary key (flight_number, seat_number,day),
foreign key (flight_number, seat_number) references seat ) ,
foreign key (passenger_ID) references passenger ;
我被困在这个问题中: 查找从“ALB”出发的预订航班(或多个航班)的每位乘客的身份证明,并且从未预订到达“ALB”的航班。对于此查询,请使用in子句或not in子句。
我写了这么多查询:
select a.passenger_id from
reservation a
where a.flight_number in (select b.flight_number from flight b where
b.departure_airport = 'ALB'
and b.arrival_airport <> 'ALB');
但是这个查询不正确。子查询返回与过滤条件匹配的所有航班号。但是主选择查询返回子查询返回的flight_number的所有乘客ID,即使该乘客的arrival_airport是ALB。
我的预订表:
passenger_id flight_number seat_number day fare
2 A2 201 10/1/17 1083
1 A3 301 10/1/17 1173.25
1 A4 402 10/1/17 846.81
2 A5 501 10/1/17 752.72
1 A5 502 10/1/17 485
4 A5 506 10/1/17 970
2 A6 601 10/1/17 388
1 A7 703 10/1/17 921.5
3 A7 704 10/1/17 921.5
2 A8 804 10/1/17 970
4 A8 805 10/1/17 970
我的航班表:
flight_number departure_airport arrival_airport
A1 Ktm Pkr
A2 Ktm NY
A3 Ktm Ind
A4 Ktm Chn
A5 ALB KTM
A6 ALB PKR
A7 KTM ALB
A8 PKR ALB
答案 0 :(得分:2)
思考:两个条件。所以从你的思路来看:
select r.passenger_id
from reservation r
where r.flight_number in (select f.flight_number
from flight f
where f.departure_airport = 'ALB'
) and
r.flight_number not in (select f.flight_number
from flight f
where f.arrival_airport = 'ALB'
);
然而,这不是那样做的。抵达ALB的任何航班都从其他机场出发。因此,这只是选择从ALB预订航班的所有乘客。此逻辑位于航班级别,而不是乘客级别。
Hmmmm。您实际上需要有关客户“一次性”所有航班的信息。这表明聚合:
select r.passenger_id
from reservation r join
flight f
on r.flight_number = f.flight_number
group by r.passenger_id
having sum(case when f.departure_airport = 'ALB' then 1 else 0 end) > 0 and -- reserved a flight from ALB
sum(case when f.arrival_airport = 'ALB' then 1 else 0 end) = 0; -- never reserved a flight to ALB
答案 1 :(得分:1)
为了以稍微不同的方式证明@ GordonLinoff答案的正确性,让我们稍微看一下它。 :-)(See this SQLFiddle)。 (请注意,我填写了PASSENGER表。我们稍后会使用它。:-)。首先,让我们抓住所有预订至少一架从ALB起飞的航班的乘客:
-- Find passengers who have reserved at least one flight departing from ALB
SELECT DISTINCT r.PASSENGER_ID
FROM RESERVATION r
INNER JOIN FLIGHT f
ON f.FLIGHT_NUMBER = r.FLIGHT_NUMBER
WHERE f.DEPARTURE_AIRPORT = 'ALB';
这将返回PASSENGER_ID的1,2和4。
接下来,让我们找到至少有一班航班抵达ALB的所有乘客:
-- Find passengers who have reserved at least one flight arriving at ALB
SELECT DISTINCT r.PASSENGER_ID
FROM RESERVATION r
INNER JOIN FLIGHT f
ON f.FLIGHT_NUMBER = r.FLIGHT_NUMBER
WHERE f.ARRIVAL_AIRPORT = 'ALB';
这将返回PASSENGER_ID的1,2,3和4。
对上述结果进行的微不足道的检查清楚地表明,没有乘客预订了从ALB起飞的航班,他们没有预订到达ALB的航班。但是因为我们想让查询向我们展示我们想要的东西而不是必须思考(毕竟,这就是计算机应该做的事情:-)我们将把上述查询放在一起:
-- Now put them together
SELECT p.PASSENGER_ID
FROM PASSENGER p
INNER JOIN (SELECT DISTINCT r.PASSENGER_ID
FROM RESERVATION r
INNER JOIN FLIGHT f
ON f.FLIGHT_NUMBER = r.FLIGHT_NUMBER
WHERE f.DEPARTURE_AIRPORT = 'ALB') d
ON d.PASSENGER_ID = p.PASSENGER_ID
LEFT OUTER JOIN (SELECT DISTINCT r.PASSENGER_ID
FROM RESERVATION r
INNER JOIN FLIGHT f
ON f.FLIGHT_NUMBER = r.FLIGHT_NUMBER
WHERE f.ARRIVAL_AIRPORT = 'ALB') a
ON a.PASSENGER_ID = p.PASSENGER_ID
WHERE a.PASSENGER_ID IS NULL;
此查询不会按预期返回任何结果。
但是......我们确实希望确保我们的查询确实有效。 Soooo ...让我们在几个表中添加几行。首先,我们将添加一名新乘客:
insert into passenger (passenger_ID, passenger_name, passenger_city)
values ('5', 'Bugs Bunny', 'ABC');
我们将为Bunny先生添加一个航班,他将离开ALB:
INSERT INTO RESERVATION (PASSENGER_ID, FLIGHT_NUMBER, SEAT_NUMBER, DAY, FARE)
VALUES ('5', 'A6', '123', TO_DATE('2017-10-01','YYYY-MM-DD'), 400);
所以现在我们有乘客5,B.Bunny先生,离开ALB - 但他从未飞入ALB。 (我想那是因为他应该在阿尔伯克基左转:-)。所以我们的查询应该返回乘客5,而if you go look at this SQLFiddle你会看到正是发生的事情。
嗯 - 祝你好运,医生。
答案 2 :(得分:1)
使用IN()
和NOT IN()
SELECT DISTINCT
r.passenger_id
FROM reservation r
WHERE r.passenger_id IN (
SELECT
r.passenger_id
FROM RESERVATION r
INNER JOIN FLIGHT f ON f.flight_number = r.flight_number
WHERE f.DEPARTURE_AIRPORT = 'ALB'
)
AND r.passenger_id NOT IN (
SELECT
r.passenger_id
FROM RESERVATION r
INNER JOIN FLIGHT f ON f.flight_number = r.flight_number
WHERE f.ARRIVAL_AIRPORT = 'ALB'
)
;
但Bob Jarvis的分析确实显示样本数据中没有行符合分配标准。