How to select output from multi tables? - mysql

Bus
+----------+-------------+-------------+
| route_no | Start_point | destination |
+----------+-------------+-------------+
| 123 | ABC | BCD |
| 234 | DEF | EFG |
| 345 | GHI | HIJ |
| 445 | JKL | KLM |
| 546 | MNO | NOP |
+----------+-------------+-------------+
Passenger
+-----+--------+--------+------+
| pid | pname | gender | age |
+-----+--------+--------+------+
| 111 | David | m | 30 |
| 222 | Andy | f | 20 |
| 333 | kat | f | 27 |
| 444 | viki | m | 32 |
| 555 | rob | m | 52 |
+-----+--------+--------+------+
Booking
+-----+----------+------------+---------+
| pid | route_no | jrny_date | seat_no |
+-----+----------+------------+---------+
| 111 | 123 | 2019-05-14 | 57 |
| 222 | 234 | 2019-06-11 | 3 |
| 333 | 345 | 2019-07-20 | 33 |
| 444 | 445 | 2018-08-22 | 14 |
| 555 | 546 | 2018-11-17 | 19 |
+-----+----------+------------+---------+`
1)I am trying to display all passengers on route_no=123 traveling from ABC to BCD.
2) Displaying all pid and gender of all passengers traveling on route_no=345 on the current date.
select passenger.*
from passeger
, bus
, booking
where passenger.pid = booking.pid;
ERROR 1146 (42S02): Table 'travel_agency.passenger' doesn't exist`

mysql> select passenger.* from passeger,bus,booking where passenger.pid=booking.
pid;
Is passenger ? probably this mistake.
To your answer query here:
1)
select passenger.pname, passenger.gender, passenger.age, bus.Start_point, bus.destination from passenger,bus,booking where passenger.pid=booking.pid and booking.route_no= bus.route_no and bus.route_no=123;
2)
select passenger.pname, passenger.gender, booking.jrny_date from passenger,booking where passenger.pid=booking.pid and booking.route_no=345;

Related

How to subtract the sum of value using left join?

I have two tables orders and customers:
select * from orders;
+------+---------------------+-------------+--------+
| oid | date | customer_id | amount |
+------+---------------------+-------------+--------+
| 102 | 2009-10-08 00:00:00 | 4 | 300 |
| 100 | 2009-10-08 00:00:00 | 3 | 15000 |
| 101 | 2008-10-08 00:00:00 | 2 | 1300 |
| 105 | 2010-10-08 00:00:00 | 1 | 400 |
| 106 | 2014-12-23 00:00:00 | 3 | 300 |
+------+---------------------+-------------+--------+
select * from customers;
+------+--------+------+-----------+----------+
| id | name | age | address | salary |
+------+--------+------+-----------+----------+
| 1 | ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | khilan | 25 | delhi | 1500.00 |
| 3 | muffy | 22 | bhopal | 8500.00 |
| 4 | suresh | 48 | mumbai | 24000.00 |
| 1 | ramesh | 32 | Ahmedabad | 300.00 |
| 5 | akil | 21 | madurai | 1000.00 |
| 6 | rajesh | 22 | delhi | 5000.00 |
+------+--------+------+-----------+----------+
What I'm trying to do is to do SUM(salary) from customers and subtract it with the SUM(amount) from orders table. I have tried with this query:
SELECT id ,NAME,SUM(salary),SUM(amount),SUM(salary)-SUM(amount)
FROM customers a LEFT JOIN orders b ON a.id=b.customer_id
GROUP BY NAME;
This will return the following result, which some of them return incorrect value:
+------+--------+-------------+-------------+-------------------------+
| id | name | SUM(salary) | SUM(amount) | SUM(salary)-SUM(amount) |
+------+--------+-------------+-------------+-------------------------+
| 5 | akil | 1000.00 | NULL | NULL |
| 2 | khilan | 1500.00 | 1300 | 200.00 |
| 3 | muffy | 17000.00 | 15300 | 1700.00 |
| 6 | rajesh | 5000.00 | NULL | NULL |
| 1 | ramesh | 2300.00 | 800 | 1500.00 |
| 4 | suresh | 24000.00 | 300 | 23700.00 |
+------+--------+-------------+-------------+-------------------------+
My expected output is as following:
+------+--------+-------------+-------------+-------------------------+
| id | name | SUM(salary) | SUM(amount) | SUM(salary)-SUM(amount) |
+------+--------+-------------+-------------+-------------------------+
| 5 | akil | 1000.00 | NULL | 1000 |
| 2 | khilan | 1500.00 | 1300 | 200.00 |
| 3 | muffy | 8500 | 15300 | -6800 |
| 6 | rajesh | 5000.00 | NULL | 5000 |
| 1 | ramesh | 2300.00 | 400 | 1900.00 |
| 4 | suresh | 24000.00 | 300 | 23700.00 |
+------+--------+-------------+-------------+-------------------------+
One way is to make calculation on orders into sub-query.
To cater for NULL value, you can use IFNULL(value,0).
SELECT id,NAME,SUM(salary),amt,SUM(salary)-IFNULL(amt,0)
FROM customers a LEFT JOIN
(SELECT customer_id, SUM(amount) amt FROM orders GROUP BY customer_id) b
ON a.id=b.customer_id
GROUP BY NAME;

Query for arrival time, departure time, and total distance between source, destination, and connecting trains

I have a table train_schedule
| id | train_no |train_name | station_no|station_code|arr_time| dep_time | distance|src_station_code|dest_station_code|
-----------------------------------------------------------------------------------------------------------------------------
| 1 | 0123 | ABC | 1 | ROU |00:00:00| 06:00:00 | 0 | ROU | BBS |
| 2 | 0123 | ABC | 2 | CLM |06:50:00| 06:55:00 | 100 | ROU | BBS |
| 3 | 0123 | ABC | 3 | GNT |07:30:00| 07:32:00 | 150 | ROU | BBS |
| 4 | 0123 | ABC | 4 | BBS |08:30:00| 00:00:00 | 300 | ROU | BBS |
-----------------------------------------------------------------------------------------------------------------------------
| 5 | 0224 | XYZ | 1 | HTE |00:00:00| 09:00:00 | 0 | HTE | BBS |
| 6 | 0224 | XYZ | 2 | ROU |09:51:00| 09:56:00 | 200 | HTE | BBS |
| 7 | 0224 | XYZ | 3 | BBS |10:30:00| 00:00:00 | 550 | HTE | BBS |
-----------------------------------------------------------------------------------------------------------------------------
| 8 | 0774 | PQR | 1 | NDLS |00:00:00| 02:00:00 | 0 | NDLS | BNC |
| 9 | 0774 | PQR | 2 | ROU |04:50:00| 04:56:00 | 200 | NDLS | BNC |
| 10 | 0774 | PQR | 3 | BBS |06:30:00| 06:45:00 | 450 | NDLS | BNC |
| 11 | 0774 | PQR | 4 | BNC |10:30:00| 00:00:00 | 550 | NDLS | BNC |
User will give input as a source and destination for ex: ROU and BBS
Output will be 3 train for this selection, with train_no,arr_time,dep_time,and total distance, i tried with different possibilities able to get trains between sorce and destination but not connecting trains.
Desired result:
| id | train_no |train_name | station_code|dep_time| arr_time | distance | FROM | TO |
------------------------------------------------------------------------------------------------------------------
| 1 | 0123 | ABC | ROU |06:00:00| 08:30:00 | 300 | ROU | BBS |
| 2 | 0224 | XYZ | ROU |09:56:00| 10:30:00 |550-200=350| ROU | BBS |
| 3 | 0774 | PQR | ROU |04:56:00| 06:30:00 |450-200=250| ROU | BBS |
I have tried with following query though it gives the desired result but only with the train between src_station_code and destination_station_code I want connecting trains also.
select FirstSet.train_no, FirstSet.total_distance, FirstSet.arrival_time, FirstSet.source_station_code, FirstSet.source_station_name, FirstSet.destination_station_code, FirstSet.destination_station_name, SecondSet.departure_time
from
( SELECT train_no, MAX(distance) AS total_distance, arrival_time,train_name,source_station_code,destination_station_code,source_station_name,destination_station_name FROM train_schedule as q where distance = (select max(distance) from train_schedule where train_no = q.train_no)and (src_stn_code='ROU' and dst_stn_code='BBS') GROUP BY train_no )
as FirstSet left join
( SELECT train_no,source_station_code,departure_time FROM train_schedule where station_no='1' and (src_stn_code='ROU' and dst_stn_code='BBS') ) as SecondSet on FirstSet.train_no = SecondSet.train_no order by FirstSet.train_no
I've put your data and the solution in this sqlfiddle.
Here is the solution SQL to your question (but missing the new id for the result):
SELECT ts1.train_no,ts1.train_name,ts1.station_code,ts1.dep_time,ts2.arr_time,
ts2.distance -ts1.distance As distance,
ts1.station_code AS 'FROM', ts2.station_code AS 'TO'
FROM train_schedule ts1 JOIN train_schedule ts2
ON ts1.train_no = ts2.train_no AND ts1.station_no < ts2.station_no
WHERE ts1.station_code = 'ROU' AND ts2.station_code = 'BBS';

SQL select data and count from multiple tables given there's a common column in each

Given the following three tables:
Table: A Table: B Table: C
+----+-----+ +-----+--------+ +--------+----------+
| id | cid | | cid | cat_id | | cat_id | cat_name |
+----+-----+ +-----+--------+ +--------+----------+
| 1 | 33 | | 33 | 6 | | 1 | AAAAA |
| 2 | 33 | | 33 | 20 | | 2 | BBBBB |
| 3 | 33 | | 33 | 59 | | 3 | CCCCC |
| 4 | 33 | | 33 | 88 | | 4 | DDDDD |
| 5 | 33 | | 35 | 8 | | 5 | EEEEE |
| 6 | 86 | | 86 | 1 | | 6 | FFFFF |
| 7 | 86 | | 86 | 14 | | 7 | GGGGG |
| 8 | 99 | | 86 | 45 | | 14 | HHHHH |
| 9 | 100 | | 86 | 57 | | 20 | IIIII |
+----+-----+ | 86 | 59 | | 42 | JJJJJ |
| 86 | 94 | | 45 | KKKKK |
| 98 | 5 | | 57 | MMMMM |
| 99 | 42 | | 58 | NNNNN |
| 100 | 75 | | 59 | OOOOO |
+-----+--------+ | 75 | PPPPP |
| 88 | QQQQQ |
| 89 | RRRRR |
| 90 | SSSSS |
| 91 | TTTTT |
| 92 | UUUUU |
| 93 | VVVVV |
| 94 | WWWWW |
| 95 | XXXXX |
| 96 | YYYYY |
| 97 | ZZZZZ |
+--------+----------+
I would like to get:
Result 1:
+-----+--------+----------+-------------+
| cid | cat_id | cat_name | Total_Click | Total_Click = count(cid) from table A
+-----+--------+----------+-------------+
| 33 | 6 | FFFFF | 5 |
| 33 | 20 | IIIII | 5 |
| 33 | 59 | OOOOO | 5 |
| 33 | 88 | QQQQQ | 5 |
| 86 | 1 | AAAAA | 2 |
| 86 | 14 | HHHHH | 2 |
| 86 | 45 | KKKKK | 2 |
| 86 | 57 | MMMMM | 2 |
| 86 | 59 | OOOOO | 2 |
| 86 | 94 | WWWWW | 2 |
| 99 | 42 | JJJJJ | 1 |
| 100 | 75 | PPPPP | 1 |
+-----+--------+----------+-------------+
Ultimately, I would like to know the number of clicks each category received.
Result 2:
+----------+-------------+
| cat_name | Total_Click |
+----------+-------------+
| AAAAA | 2 |
| BBBBB | 0 |
| CCCCC | 0 |
| DDDDD | 0 |
| EEEEE | 0 |
| FFFFF | 5 |
| GGGGG | 0 |
| HHHHH | 2 |
| IIIII | 5 |
| JJJJJ | 1 |
| KKKKK | 2 |
| LLLLL | 0 |
| MMMMM | 2 |
| NNNNN | 0 |
| OOOOO | 7 |
| PPPPP | 1 |
| QQQQQ | 5 |
| RRRRR | 0 |
| SSSSS | 0 |
| TTTTT | 0 |
| UUUUU | 0 |
| VVVVV | 0 |
| WWWWW | 2 |
| XXXXX | 0 |
| YYYYY | 0 |
| ZZZZZ | 0 |
+----------+-------------+
Thanks!
Your first result can be obtained by doing a JOIN
SELECT a.cid, b.cat_id, c.cat_name, COUNT(a.id) as Click
FROM Table_c c
JOIN Table_b b ON c.cat_id = b.cat_id
JOIN Table_a a ON a.cid = b.cid
GROUP BY c.cat_name, a.cid, b.cat_id
Try the following query for your second result
SELECT c.cat_name, IFNULL(COUNT(a.id), 0) as Total_Click
FROM Table_c c
LEFT OUTER JOIN Table_b b ON c.cat_id = b.cat_id
LEFT OUTER JOIN Table_a a ON a.cid = b.cid
GROUP BY c.cat_name

MySQL information from another table

I have the following SQL:
Select roleid , deity_level FROM default_jd_deity_role LIMIT 10;
That gives the output:
+--------+-------------+
| roleid | deity_level |
+--------+-------------+
| 1024 | 1 |
| 1043 | 54 |
| 1056 | 1 |
| 1057 | 54 |
| 1072 | 54 |
| 1074 | 45 |
| 1075 | 36 |
| 1088 | 45 |
| 1089 | 45 |
| 1104 | 27 |
+--------+-------------+
Then I have this SQL:
Select roleid , name FROM default_jd_ingame_roles LIMIT 22, 10
That gives the following output:
+--------+---------+
| roleid | name |
+--------+---------+
| 1024 | Hulu |
| 1043 | Cookiez |
| 1056 | Sam |
| 1057 | Sugar |
| 1072 | Leah |
| 1073 | Smexy |
| 1074 | Bam! |
| 1075 | Lexi |
| 1088 | OneShot |
| 1089 | Demono |
+--------+---------+
What I am trying to do is make deity_level add on to the second SQL Query like this:
+--------+---------+-------------+
| roleid | name | deity_level |
+--------+---------+-------------+
| 1024 | Hulu | 1 |
| 1043 | Cookiez | 54 |
| 1056 | Sam | 1 |
| 1057 | Sugar | 54 |
| 1072 | Leah | 54 |
| 1073 | Smexy | 45 |
| 1074 | Bam! | 36 |
| 1075 | Lexi | 45 |
| 1088 | OneShot | 45 |
| 1089 | Demono | 27 |
+--------+---------+-------------+
Try this:
Select a.roleid , a.deity_level, b.name
FROM default_jd_deity_role AS a
JOIN default_jd_ingame_roles AS b ON a.roleid=b.roleid
LIMIT 10
You can achieve this with a JOIN, like this:
SELECT main.roleid, roles.name, main.deity_level
FROM default_jd_deity_role main
LEFT JOIN default_jd_ingame_roles roles ON main.roleid = roles.roleid
LIMIT 22, 10
I'll leave two nice tutorials to get you started on JOINS:
http://www.sitepoint.com/understanding-sql-joins-mysql-database/
http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
You are looking for a JOIN query:
SELECT igr.roleid , igr.name, dr.diety_level
FROM default_jd_ingame_roles igr
JOIN default_jd_deity_role dr ON dr.roleid = igr.roleid

Group rows with sum and join (Build summary)

There is a rowset like this:
| ID | OP_CODE | OWNER | MEASURE | COUNT |
|----|-------------|-------|----------|-------|
| 1 | Operation 1 | 1 | Geometry | 42 |
| 2 | Operation 1 | 1 | Geometry | 48 |
| 3 | Operation 1 | 1 | Vacuum | 29 |
| 4 | Operation 1 | 1 | Electro | 14 |
| 5 | Operation 1 | 2 | Geometry | 87 |
| 6 | Operation 1 | 2 | Geometry | 112 |
| 7 | Operation 1 | 2 | Vacuum | 78 |
| 8 | Operation 1 | 3 | Vacuum | 56 |
| 9 | Operation 1 | 3 | Electro | 78 |
I want to group rows by Owner and merge/join other Measures (values of column MEASURE) with sum of column Count to this result like this:
| OWNER | GEOMETRY_CNT | VACUUM_CNT | ELECTRO_CNT | TOTAL_CNT |
|-------|--------------|------------|-------------|-----------|
| 1 | 90 | 29 | 14 | 133 |
| 2 | 199 | 78 | (null) | 277 |
| 3 | (null) | 56 | 78 | 134 |
In this case Geometry_cnt, Vacuum_cnt, Electro_cnt is a sum of corresponding values in first table:
Owner_1_Geometry_cnt=42+48=90;
Owner_1_Vacuum_cnt=29;
Owner_1_Electro_cnt=14;
Owner_1_TOTAL=29+14+90=133;
How can I get this rowset?
SQL Fiddle
Try this:
SELECT a.OWNER, SUM(IF(a.MEASURE = 'Geometry', a.COUNT, 0)) GEOMETRY_CNT,
SUM(IF(a.MEASURE = 'Vacuum', a.COUNT, 0)) VACUUM_CNT,
SUM(IF(a.MEASURE = 'Electro', a.COUNT, 0)) ELECTRO_CNT,
SUM(a.COUNT) TOTAL_CNT
FROM operations_schedule a
GROUP BY a.OWNER
Check the SQL FIDDLE DEMO
OUTPUT
| OWNER | GEOMETRY_CNT | VACUUM_CNT | ELECTRO_CNT | TOTAL_CNT |
|-------|--------------|------------|-------------|-----------|
| 1 | 90 | 29 | 14 | 133 |
| 2 | 199 | 78 | 0 | 277 |
| 3 | 0 | 56 | 78 | 134 |