How do I combine 3 tables in mysql - mysql

I need some help here
I have 3 tables which looked like:
user_base_info
+-------+-----------+------------------+------------------+------------------+------------------+
|user_id| real_name | live_province | live_city | live_area_big | live_area_small |
+-------+-----------+------------------+------------------+------------------+------------------+
| 1 | John | 15000000 | 15300000 | 15310000 | 15310003 |
| 2 | Susan | 42000000 | 42140000 | 42140400 | 42140401 |
| 3 | Andy | 12000000 | 58300000 | 58302000 | 58302004 |
| 4 | Knoxvile | 12000000 | 12100000 | 12110000 | 12110002 |
| 5 | Abraham | 13000000 | 50200000 | 50200000 | 11115007 |
| ... | ........ | ... | ... | ... | ... |
|331508 | Donald | 41000000 | 41010000 | 41011200 | 41011202 |
+-------+-----------+------------------+------------------+------------------+------------------+
borrow_progress
+--------+-----------+------------+------------+-------------+
|user_id | borrow_id | state | remark | create_time |
+--------+-----------+------------+------------+-------------+
| 170 | 236 | 10 | waiting | 24/04/17 |
| 170 | 236 | 22 | proceed | 02/02/17 |
| 170 | 236 | 26 | success | 25/04/17 |
| 170 | 236 | 30 | sent | 05/11/17 |
| 172 | 237 | 40 | completed | 03/07/17 |
| ... | ... | ... | ... | ... |
| 353252 | 24112 | 90 | failed | 30/01/17 |
+--------+-----------+------------+------------+-------------+
area
+------------+---------------------+
|code | name |
+------------+---------------------+
| 11000000 | Jawa Tengah |
| 12000000 | Jawa Barat |
| 13000000 | Jawa Timur |
| 14000000 | Sumatera Utara |
| 15000000 | DKI Jakarta |
| ... | ... |
| 41000000 | Di Yogyakarta |
| 42140000 | Kota Singkawang |
| 58300000 | Kota Depok |
| 12100000 | Bandung |
| 50200000 | Kabupaten Sukoharjo |
| 41010000 | Kabupaten Sleman |
| 15310000 | Cilandak |
| 42140400 | Singkawang Barat |
| 41011200 | Mlati |
| 12110000 | Arjasari |
| 15310003 | Gandaria Selatan |
| 41011202 | Sinduadi |
+------------+---------------------+
I want to select the user in table user_base_info which has state = 90 in table borrow_progress and change the live_province, live_city, live_area_big, live_area_small code with name in table area.
I want the result looks like this:
+-------+-----------+------------------+------------------+------------------+------------------+
|user_id| real_name | live_province | live_city | live_area_big | live_area_small |
+-------+-----------+------------------+------------------+------------------+------------------+
|331508 | Donald | Di Yogyakarta | Kabupaten Sleman | Mlati | Sinduadi |
+-------+-----------+------------------+------------------+------------------+------------------+
I have tried
SELECT
*
FROM
borrow_progress a
INNER JOIN
user_base_info b ON a.user_id = b.user_id
INNER JOIN
area c ON c.code = b.live_city
WHERE
state = 90
But this is not what I want.

You must join 4 copies of the table area to the other 2 tables.
Each copy of area will return the name for each of the 4 columns: live_province, live_city, live_area_big and live_area_small:
select u.user_id, u.real_name,
a1.name live_province,
a2.name live_city,
a3.name live_area_big,
a4.name live_area_small
from user_base_info u
inner join borrow_progress b on b.user_id= u.user_id
inner join area a1 on a1.code = u.live_province
inner join area a2 on a2.code = u.live_city
inner join area a3 on a3.code = u.live_area_big
inner join area a4 on a4.code = u.live_area_small
where b.state = 90
If there is a case that the columns live_province, live_city, live_area_big and live_area_small in the table user_base_info to be null then use left joins instead of inner joins.
See the demo.
Results:
| user_id | real_name | live_province | live_city | live_area_big | live_area_small |
| ------- | --------- | ------------- | ---------------- | ------------- | --------------- |
| 331508 | Donald | Di Yogyakarta | Kabupaten Sleman | Mlati | Sinduadi |

Try this:
SELECT
b.user_id
, b.real_name
, (select c1.name from area c1 where code = a.live_province) "live_province"
, live_city
, (select c2.name from area c2 where code = a.live_area_big) "live_area_big"
, (select c3.name from area c3 where code = a.live_area_big) "live_area_small"
FROM borrow_progress a
INNER JOIN user_base_info b ON a.user_id = b.user_id
INNER JOIN area c ON c.code = b.live_city
WHERE state = 90

Related

MySQL select statement missing some fields

I have following statement that is used to select some fields from MySQL DB
select finance_budget_issue.budget_date, SUM(finance_budget_issue.amount) AS amount, finance_vote.office_id as vote_office_id, finance_office.office_head as head,
finance_office.office_name AS office_name,
finance_budget.ref_no, finance_budget_issue.view_status, tbl_signature.office_head as sign_office_head, tbl_signature.name AS name,
tbl_signature.post AS post, tbl_signature.sign_id
from finance_budget_issue
inner join finance_budget on finance_budget.budget_id=finance_budget_issue.budget_id
left join finance_vote on finance_budget_issue.vote_id=finance_vote.vote_id
left join finance_vote_description on finance_vote.description=finance_vote_description.vote_description_id
left join finance_office on finance_budget_issue.office=finance_office.office_id
left join tbl_signature on finance_office.office_id=tbl_signature.office_id
The statement is working fine, but didn't outs the following fields
tbl_signature.office_head as sign_office_head,
tbl_signature.name AS name,
tbl_signature.post AS post
What may be going wrong ? I think that I used incorrect Joins. Can anyone help ?
Tables as follows :
finance_office
+----+-----------+-------------+------+
| id | office_id | office_name | head |
+----+-----------+-------------+------+
| 1 | 48 | A | SS |
| 2 | 69 | B | VV |
+----+-----------+-------------+------+
finance_vote
+---------+-----------+----------------+
| vote_id | office_id | vote |
+---------+-----------+----------------+
| 1 | 48 | 320-1-2-1-1001 |
| 2 | 48 | 320-2-2-2-2002 |
| 3 | 69 | 319-1-2-1-1001 |
| 4 | 69 | 319-1-2-2-1102 |
| 5 | 30 | 318-1-1-2-1101 |
+---------+-----------+----------------+
tbl_signature
+---------+-----------+---------+------------+-------------+
| sign_id | office_id | name | post | office_head |
+---------+-----------+---------+------------+-------------+
| 1 | 48 | Noel | Accountant | Manager |
| 2 | 69 | Jhon | Accountant | Manager |
| 3 | 30 | Micheal | Accountant | Manager |
+---------+-----------+---------+------------+-------------+
finance_budget
+-----------+--------+-------------+
| budget_id | ref_no | budget_date |
+-----------+--------+-------------+
| 1 | Acc/01 | 2020-01-20 |
| 2 | Acc/02 | 2020-01-22 |
+-----------+--------+-------------+
finance_budget_issue
+----+-----------+--------+---------------+-----------------+
| id | budget_id | amount | budget_status | transfer_status |
+----+-----------+--------+---------------+-----------------+
| 1 | 1 | 75000 | issues | Approved |
| 2 | 1 | 22000 | issues | Approved |
| 3 | 2 | 65000 | issues | Approved |
+----+-----------+--------+---------------+-----------------+
Desired Output
+--------+----------------+------+--------+------------------+------+------------+
| amount | vote_office_id | head | ref_no | sign_office_head | name | post |
+--------+----------------+------+--------+------------------+------+------------+
| 75000 | 48 | SS | Acc/01 | Manager | Noel | Accountant |
| 22000 | 48 | SS | Acc/01 | Manager | Noel | Accountant |
| 65000 | 69 | VV | Acc/02 | Manager | Jhon | Accountant |
+--------+----------------+------+--------+------------------+------+------------+
Generated Output (Incorrect)
+--------+----------------+------+--------+------------------+------+------+
| amount | vote_office_id | head | ref_no | sign_office_head | name | post |
+--------+----------------+------+--------+------------------+------+------+
| 75000 | 48 | SS | Acc/01 | | | |
| 22000 | 48 | SS | Acc/01 | | | |
| 65000 | 69 | VV | Acc/02 | | | |
+--------+----------------+------+--------+------------------+------+------+
This is easier to read:
SELECT i.budget_date
, SUM(i.amount) amount
, v.office_id vote_office_id
, o.office_head head
, o.office_name
, b.ref_no
, i.view_status
, s.office_head sign_office_head
, s.name
, s.post
, s.sign_id
FROM finance_budget_issue i
JOIN finance_budget b
ON b.budget_id = i.budget_id
LEFT
JOIN finance_vote v
ON v.vote_id = i.vote_id
LEFT
JOIN finance_vote_description d
ON d.vote_description_id = v.description
LEFT
JOIN finance_office o
ON i.office = o.office_id
LEFT
JOIN tbl_signature s
ON s.office_id = o.office_id
You have an aggregate function (and non-aggregated columns) but no GROUP BY clause; that's not going to work. You have a LEFT JOINed table from which you select no columns; that's pointless.
For further help, see Why should I provide an MCRE for what seems to me to be a very simple SQL query

MySQL Join one table to other two tables

I have a MySQL database including following tables that used to maintain transactions of some documents.
tbl_documents Table
+----+---------+------+---------+
| id | file_no | name | subject |
+----+---------+------+---------+
| 1 | A/10 | F1 | a |
| 2 | A/11 | F2 | b |
| 3 | A/12 | F3 | c |
| 4 | A/13 | F4 | d |
+----+---------+------+---------+
tbl_requests
+----+-------------+----------------+---------------+
| id | document_id | requested_date | approved_date |
+----+-------------+----------------+---------------+
| 1 | 1 | 2019-12-01 | 2019-12-02 |
| 2 | 2 | 2019-12-08 | 2019-12-08 |
+----+-------------+----------------+---------------+
tbl_issues
+----+-------------+------------+
| id | document_id | issue_date |
+----+-------------+------------+
| 1 | 1 | 2019-12-05 |
| 2 | 2 | 2019-12-10 |
+----+-------------+------------+
I want to get the following / Desired output by joining above three tables.
Desired Output
+---------+------+---------+----------------+---------------+------------+
| file_no | name | subject | requested_date | approved_date | issue_date |
+---------+------+---------+----------------+---------------+------------+
| A/10 | F1 | a | 2019-12-01 | 2019-12-02 | 2019-12-05 |
| A/11 | F2 | b | 2019-12-08 | 2019-12-08 | 2019-12-10 |
+---------+------+---------+----------------+---------------+------------+
To do that, I used the following query
select tbl_documents.file_no, tbl_documents.name, tbl_documents.subject, requested_date, approved_date, tbl_issues.issue_date
from tbl_documents
right join tbl_requests on tbl_requests.document_id=tbl_documents.id
right join tbl_issues on tbl_issues.document_id=tbl_documents.id
But didn't get the expected output. Can anyone help ?
Just use inner joins, as in:
select
d.file_no,
d.name,
d.subject,
r.requested_date,
r.approved_date,
i.issue_date
from tbl_documents d
join tbl_requests r on r.document_id = d.id
join tbl_issues i on i.document_id = d.id

select a table's items with other tables that have multiple rows with multiple criteria - MYSQL

I have these tables ;
Mysql Tables[Click Here]
attendance table
+-----+------------+--------+---------+--+
| id | atdnc_date | emp_id | isleave | |
+-----+------------+--------+---------+--+
| 138 | 2018-11-22 | 1024 | 1 | |
| 133 | 2018-11-21 | 6 | 0 | |
| 130 | 2018-11-20 | 6 | 0 | |
| 129 | 2018-11-20 | 71 | 1 | |
| 126 | 2018-11-19 | 817 | 0 | |
| 122 | 2018-11-18 | 355 | 0 | |
| 123 | 2018-11-18 | 6 | 0 | |
| 190 | 2018-11-17 | 355 | 1 | |
| 119 | 2018-11-17 | 817 | 0 | |
| 117 | 2018-11-17 | 6 | 0 | |
| 116 | 2018-11-17 | 71 | 0 | |
| 113 | 2018-11-16 | 817 | 0 | |
+-----+------------+--------+---------+--+
driver table
+-----+-----------+-------------+--+
| id | driver_id | driver_lice | |
+-----+-----------+-------------+--+
| 131 | 817 | B67408 | |
| 132 | 450 | B548093 | |
| 133 | 6 | B1394007 | |
| 134 | 355 | B772739 | |
| 135 | 1024 | B204085 | |
| 136 | 71 | B2442775 | |
| 137 | 88881 | B2056537 | |
| 138 | 729 | B8265 | |
| 139 | 600 | B393570 | |
| 140 | 748 | B2228230 | |
+-----+-----------+-------------+--+
vehicle table
+-----+---------------+-----------+--+
| id | vehicle_id | driver_id | |
+-----+---------------+-----------+--+
| 137 | VH000137 | 817 | |
| 138 | VH000138 | 817 | |
| 139 | VH000139 | 600 | |
| 140 | VH000140 | 1024 | |
| 141 | VH000141 | 450 | |
| 142 | VH000142 | 600 | |
| 143 | VH000143 | 729 | |
| 144 | VH000144 | 817 | |
+-----+---------------+-----------+--+
vehicle_status table
+---------------+----------+----------------+--+
| vehicle_id | order_id | current_status | |
+---------------+----------+----------------+--+
| VH000137 | OR000130 | completed | |
| VH000138 | OR000131 | arrived_to_sup | |
| VH000139 | OR000132 | completed | |
| VH000140 | OR000133 | cancelled | |
| VH000141 | OR000134 | completed | |
| VH000142 | OR000135 | arrived_to_sup | |
| VH000143 | OR000136 | arrived_to_sup | |
| VH000144 | OR000137 | completed | |
+---------------+----------+----------------+--+
And i want get list of all drivers that ,
attendance.atdnc_date <> '2018-11-17' AND attendance.isleave<>1
OR that attendance row is null according to driver
AND
vehicle_status.current_status = 'cancelled' OR vehicle_status.current_status = 'completed'
OR, OR that vehicle_status row is null according to driver
here i tried queries:
1)
SELECT * FROM
(SELECT driver.* FROM driver LEFT JOIN (SELECT vehicle.* FROM vehicle_status INNER JOIN vehicle ON vehicle_status.vehicle_id=vehicle.vehicle_id WHERE current_status <> 'completed' AND current_status <> 'cancelled') k
ON driver.driver_id=k.driver_id INNER JOIN(SELECT driver.driver_id FROM driver LEFT JOIN (SELECT emp_id FROM `attendance` WHERE isleave=1 AND atdnc_date='2018-11-17') as x ON x.emp_id=driver.driver_id WHERE x.emp_id IS NULL ) d ON driver.driver_id=d.driver_id ) as x
2)
SELECT * FROM driver
LEFT JOIN vehicle ON driver.driver_id=vehicle.driver_id
LEFT JOIN vehicle_status ON vehicle.vehicle_id=vehicle_status.vehicle_id
LEFT JOIN attendance ON driver.driver_id=attendance.emp_id WHERE (vehicle_status.current_status ="completed" OR vehicle_status.current_status ="cancelled" OR vehicle_status.current_status IS NULL)
AND ((attendance.atdnc_date = '2018-11-17' AND attendance.isleave = 0) OR (attendance.atdnc_date IS NULL) ) GROUP BY driver.driver_id
3)
SELECT * FROM (SELECT driver.* FROM driver LEFT JOIN (SELECT vehicle.* FROM vehicle_status INNER JOIN vehicle ON vehicle_status.vehicle_id=vehicle.vehicle_id WHERE current_status <> 'completed' AND current_status <> 'cancelled') k ON driver.driver_id=k.driver_id WHERE k.driver_id IS NULL) x
INNER JOIN (SELECT driver.* FROM driver LEFT JOIN attendance ON driver.driver_id=attendance.emp_id WHERE ((attendance.atdnc_date <> '2018-11-17' AND attendance.isleave <> 0) OR (attendance.atdnc_date IS NULL) )) b ON x.driver_id=b.driver_id
i think this working.. but can be slow when using with large set of data.
4)
select b.* FROM (SELECT driver.* FROM driver LEFT JOIN (SELECT vehicle.* FROM vehicle_status INNER JOIN vehicle ON vehicle_status.vehicle_id=vehicle.vehicle_id WHERE current_status <> 'completed' AND current_status <> 'cancelled') k
ON driver.driver_id=k.driver_id WHERE k.driver_id IS NULL) b
LEFT JOIN (SELECT driver.driver_id FROM attendance INNER JOIN driver ON attendance.emp_id=driver.driver_id WHERE attendance.atdnc_date='2018-11-17' AND attendance.isleave='1') k ON b.driver_id=k.driver_id
WHERE k.driver_id IS NULL AND status ='1'
these queries sometimes work. but when attendance, and vehicle_status have multiple rows with driver, these quires fail. and show multiple drivers or show drivers that not meet the conditions :(
expected result
+-----+-----------+-------------+--+
| id | driver_id | driver_lice | |
+-----+-----------+-------------+--+
| 132 | 450 | B548093 | |
| 133 | 6 | B1394007 | |
| 136 | 71 | B2442775 | |
| 137 | 88881 | B2056537 | |
| 138 | 729 | B8265 | |
| 140 | 748 | B2228230 | |
| 138 | 1024| B204085 | |
+-----+-----------+-------------+--+

MYSQL Complex Join one-to-many

I have the following tables:
clients:
| id | name | code | zone |
--------------------------------
| 1 | client 1 | a1b1 | zone1|
| 2 | client 2 | a2b2 | zone2|
contacts:
| id_contact | first_name | last_name |
----------------------------------------
| 11 | first1 | last1 |
| 22 | first2 | last2 |
| 33 | first3 | last3 |
| 44 | first4 | last4 |
client_contacts:
| id_client | id_contact |
--------------------------
| 1 | 11 |
| 1 | 22 |
| 1 | 33 |
| 2 | 11 |
| 2 | 44 |
offers:
| id_offer | id_client | value |
--------------------------
| 111 | 1 | 100 |
| 222 | 1 | 200 |
| 333 | 1 | 300 |
| 444 | 2 | 400 |
I would like through a optimal select to obtain:
| id_client | name | code | zone | contacts_pers | total_offer_value |
----------------------------------------------------------------------------
| 1 | client 1 | a1b1 | zone1 | first1 last1; | 600 |
first2 last2;
first3 last3;
| 2 | client 2 | a2b2 | zone2 | first1 last1; | 400 |
first4 last4;
I know how to get the desired result with "group_concat" and stored procedures for "total_offer_value". But how to get the desired result from a single efficient select?
SELECT c.id, c.name, c.code, c.zone, GROUP_CONCAT(DISTINCT CONCAT(co.first_name, " ", c.last_name) SEPARATOR ";") AS contact_pers, func_total_offer_value(c.id) AS total_offer_value
FROM clients c
LEFT OUTER JOIN (client_contacts cc, contacts co) ON ( c.id = cc.id_client AND cc.id_contact = co.id_contact )
GROUP BY c.id

How to get value from multiple tables but the value should be min and group wise

How to get value from multiple Table that should be minimum and group wise
Like:
I have Three tables
Table1 Table3
| ID | GPN | PKGID | | GPN | Amt |
| 1 | A | PKG01 | | A | 10 |
| 2 | B | PKG02 | | A | 15 |
| 3 | C | PKG03 | | A | 20 |
| 4 | D | PKG04 | | A | 25 |
| A | 65 |
| A | 30 |
----------------------------- | B | 17 |
| D | 90 |
| B | 20 |
Table2 | B | 40 |
| GPN | Date | | D | 60 |
| A | 2016-09-10 | | B | 80 |
| A | 2016-09-18 | | B | 100 |
| B | 2016-09-10 | | C | 3 |
| B | 2016-09-11 | | C | 6 |
| B | 2016-09-12 | | C | 9 |
| C | 2016-10-12 | | C | 12 |
| C | 2016-10-13 | | C | 15 |
| C | 2016-10-14 | | D | 7 |
| D | 2016-09-10 | | D | 10 |
| D | 2016-10-13 | | D | 13 |
And i have to get values from three of table so how can i do that.
For Example
Date = 2016-09-10
and i have to get values behalf of that
so result should contain all groups min value.
As Result
| ID | PKGID | GPN | Amt | Date |
| 1 | PKG01 | A | 10 | 2016-09-10 |
| 2 | PKG02 | B | 17 | 2016-09-10 |
| 4 | PKG04 | D | 7 | 2016-09-10 |
Should be this
select table.id, table1.PKGID, table1.GPN, min(table3.Amt), table2.`date`
from table1
inner join table3 on table1.GPN= table3.GPN
inner join table2 on table1.GPN= table2.GPN
where date(table2.date ) = str_to_date('2016-09-10', '%Y-%m-%d')
group by table1.GPN, table.id, table1.PKGID, table2.`date`
You can try this too
SELECT t1.*, MIN(t3.Amt) as Amt, t2.Date
FROM table1 t1
INNER JOIN table2 t2 on t1.GPN= t2.GPN
INNER JOIN table3 t3 on t1.GPN= t3.GPN
WHERE t2.Date = '2016-09-10'
GROUP BY t1.GPN
You can try something like this. First get the MIN(Amt) by grouping and then perform a JOIN
select t1.*,
xxx.Amt,
t2.`Date`
from table1 t1 join table2 t2 on t1.GPN = t2.GPN
join (select GPN, min(Amt) as Amt from table3 group by GPN) xxx
on t1.GPN = xxx.GPN;