简体   繁体   中英

How to show id from 1st table from 2 different ids from 2nd table

Database is about bus transportation so there are three tables:

STOP

 stop_id | stop_name
 --------------------
    1    | station_1
    2    | station_2
    3    | station_3

ROUTE

route_id | route_num
--------------------
1        | route_1
2        | route_2
3        | route_3

ROUTE_STOP

stop_id | route_id
------------------
1       | 1
2       | 1
1       | 2
3       | 2
1       | 3
2       | 3
3       | 3

So 1st route have stations 1 and 2, 2nd route have stations 1 and 3 while 3rd route have all station.

Trying to get route_num which goes through station_1 and station_3:

SELECT distinct(r.route_num) from STOP s
JOIN ROUTE_STOP rs 
ON s.stop_id = rs.stop_id
JOIN ROUTE_STOP r_s 
ON rs.stop_id = r_s.stop_id
JOIN ROUTE r 
ON rs.route_id = r.route_id 
WHERE s.stop_name='station_1' OR s.stop_name='station_3' 
AND rs.stop_id <> r_s.stop_id

and result should be route_2 and route_3 but it doesn't work. If there is no route between station there should be no result.

How to get route_num which goes through 2 stations and no result if there is no route between 2 stations?

Your query should be

SELECT r.route_num from route r
JOIN ROUTE_STOP rs 
ON r.route_id = rs.route_id
JOIN STOP s ON rs.stop_id = s.stop_id 
WHERE s.stop_name in ('station_1','station_3');

One way to do this is to join the tables and either use an in clause with a group by and having count() to find the matching groups, or group by route_num and use the having clause to filter the groups that have the stops you want:

-- query 1
SELECT r.route_num 
FROM ROUTE r
JOIN ROUTE_STOP rs ON r.route_id = rs.route_id
JOIN STOP s ON rs.stop_id = s.stop_id 
WHERE s.stop_name IN ('station_1','station_3')
GROUP BY r.route_num
HAVING COUNT(DISTINCT s.stop_id) = 2;

-- query 2
SELECT r.route_num 
FROM ROUTE r
JOIN ROUTE_STOP rs ON r.route_id = rs.route_id
JOIN STOP s ON rs.stop_id = s.stop_id 
GROUP BY r.route_num
HAVING (SUM(CASE WHEN s.stop_name = 'station_1' THEN 1 ELSE 0 END) = 1)
   AND (SUM(CASE WHEN s.stop_name = 'station_3' THEN 1 ELSE 0 END) = 1);

Because MySQL evaluates boolean expressions as 1 or 0 you can reduce the having clause in the last query to:

HAVING (SUM(s.stop_name = 'station_1') = 1)
   AND (SUM(s.stop_name = 'station_3') = 1);

Both queries assumes that a stop may occur more than once in a route (in the case of a route that starts and ends at the same station).

Sample SQL Fiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM