Joining three tables - Mysq-l an inner and outer join perhaps? - mysql

I am struggling to get this query to work . I have three tables and I want to do a query to get the red area.
Each circle is a table with different structure. I have managed a lot of combinations of inner joins but i specially cant get all the red areas.
A Payments : idPayment , idInvoice , Amount , date.
B Invoice : idInvoice , amount date.
C PromissoryNotes: IdNote , idInvoice, amount, date.
so far ...
SELECT B.idInvoice,A.idPayment,C.idNote FROM (Invoice b INNER JOIN payments a ON a.idInvoice=b.idInvoice) LEFT OUTER JOIN PromissoryNotes c ON c.idInvoice=b.idInvoice ORDER BY idInvoice.
DOESNT QUITE WORK
Any suggestions?

You were pretty close -- another OUTER JOIN and some WHERE criteria will do the trick:
SELECT B.idInvoice, A.idPayment, C.idNote
FROM Invoice b
LEFT JOIN payments a ON a.idInvoice=b.idInvoice
LEFT JOIN PromissoryNotes c ON c.idInvoice=b.idInvoice
WHERE a.idInvoice IS NOT NULL
OR c.idInvoice IS NOT NULL
ORDER BY B.idInvoice
What this basically says is give me all results from table B, where there's a match in table a or table c.
Condensed SQL Fiddle Demo

You could do this two ways:
1) Create a set A that is the inner join of B and A, create a set C that is the inner join of B and C, then union A and C.
2) Create a sub query that inner joins A and B, then full outer join to a sub query that inner joins C and B.
Example of 1)
SELECT b.idInvoice FROM Invoice B
JOIN Payments A on A.IdInvoice = B.IdInvoice
UNION
SELECT b.idInvoice FROM Invoice B
JOIN PromissoryNotes C on c.idInvoice = B.id Invoice
Example of 2)
SELECT idInvoice FROM
(
SELECT b.idInvoice FROM Invoice B
JOIN Payments A on A.IdInvoice = B.IdInvoice
) B FULL OUTER JOIN
(
SELECT b.idInvoice FROM Invoice B
JOIN Payments A on A.IdInvoice = B.IdInvoice
) C on b.idInvoice = C.idInvoice

Try
SELECT B.idInvoice, A.idPayment, C.idNote FROM Invoice B INNER JOIN payments A ON A.idInVoice = B.idInvoice INNER JOIN PromissoryNotes C ON C.idInvoice = B.idInvoice ORDER BY idInvoice
INNER JOIN means you get the intersection of both tables. So this is what you want.

Does this do the trick?
SELECT
ZZ.idInvoice,
ZZ.idPayment,
YY.idInvoice,
YY.idNote
FROM
(SELECT idInvoice, idPayment
FROM Invoice b
INNER JOIN payments a ON a.idInvoice=b.idInvoice) AS ZZ
FULL OUTER JOIN
(SELECT idInvoice, idNote
FROM PromissoryNotes c
INNER JOIN payments a ON a.idInvoice=c.idInvoice) AS YY ON ZZ.idInvoice = YY.idInvoice

SELECT p.idInvoice, p.idPayment, idNote
FROM Payments p JOIN Invoice i ON p.adInvoice-i.adInvoice RIGHT OUTER JOIN PromissoryNotes
UNION
SELECT i.idInvoice, idPayment, idNote
FROM Invoice i JOIN PromissoryNotes pn ON i.idInvoice=pn.idInvoice RIGHT OUTER JOIN Payments
You need to include the outer joins because the resulting tables that are to be unioned must have the same schema. I believe these are the desired fields from the query.

Related

Combine and Display query result

I have 2 query:
SELECT CustomerID,count(b.BookingStatus) as 'NotComplete'
FROM Booking b, Customer c
WHERE c.CustomerID=b.BookingCustomerID
AND(b.BookingStatus='Pending'
OR b.BookingStatus='OTW')
GROUP BY c.CustomerID
SELECT c.CustomerID, r.*
FROM Customer c,Regular r
WHERE c.CustomerID=r.RegularCID
Result:
1st query
2nd query
How to combine these 2 result together?
also, display the zero(count) as well.
Thanks!
this is what I get after few hours of trying..obviously it's not what I want..
SELECT c.CustomerID,count(b.BookingStatus) as 'NotComplete',r.RegularID
FROM Booking b, Customer c
JOIN Regular r on r.RegularCID=c.CustomerID
WHERE c.CustomerID=b.BookingCustomerID
AND (b.BookingStatus='Pending'
or b.BookingStatus='OTW'
or b.BookingStatus='Started'
or b.BookingStatus='Unclaimed'
or b.BookingStatus='Confirmed')
GROUP by r.RegularID
You can JOIN to the Regular table and then LEFT JOIN to a derived table of counts in the Booking table. We do it this way to avoid having to GROUP BY all the columns in the Regular table:
SELECT c.CustomerID, r.*, b.NotComplete
FROM Customer c
JOIN Regular r ON r.RegularCID = c.CustomerID
LEFT JOIN (SELECT BookingCustomerID, COUNT(*) AS NotComplete
FROM Booking
WHERE BookingStatus IN ('Pending', 'OTW', 'Started', 'Unclaimed', 'Confirmed')
GROUP BY BookingCustomerID) b ON b.BookingCustomerID = c.CustomerID
Use join on regular table, and subquery on your first select
SELECT t1.*, r.RegularCID FROM (
SELECT CustomerID,count(b.BookingStatus) as 'NotComplete',
FROM Booking b
INNER JOIN Customer c ON c.CustomerID=b.BookingCustomerID
WHERE (b.BookingStatus='Pending' OR b.BookingStatus='OTW')
GROUP BY c.CustomerID) t1
LEFT JOIN Regular r on r.CustomerID = t1.CustomerID

SELECT with left join and union

I have this query that return invoices made on a certain employee shift
SELECT
i.dateTime,i.amount,i.totalProfit,i.shiftID,
i_o.itemID,i_o.quantity,
item.name itemName,
p.full_name
from invoice i
LEFT JOIN
inv_order i_o on i_o.invID=i.invID
LEFT JOIN
`item-service` item on item.itemID = i_o.itemID
LEFT JOIN person p on
p.PID=i.personID
where i.shiftID =97
but then, i need to get the employee name from the employee table, and i only have the shiftID.
SELECT
i.dateTime,i.type,i.amount,i.totalProfit,i.shiftID,i_o.itemID,i_o.quantity,item.name itemName,p.full_name
from invoice i
LEFT JOIN
inv_order i_o on i_o.invID=i.invID
LEFT JOIN
`item-service` item on item.itemID = i_o.itemID
LEFT JOIN person p on
p.PID=i.personID
where i.shiftID =97
UNION
SELECT e.name from employee e
left join shift s on s.empID = e.empID
where s.shiftID =97
the mysql return this error
The used SELECT statements have a different number of columns
The error message is quite clear as to the problem: your first query returns 8 columns of data and your second only 1, so you can't UNION them. It seems you probably want to just JOIN the employee table via the shift table e.g.
SELECT i.dateTime
,i.type
,i.amount
,i.totalProfit
,i.shiftID
,i_o.itemID
,i_o.quantity
,item.name AS itemName
,p.full_name
,e.name
FROM invoice i
LEFT JOIN inv_order i_o ON i_o.invID=i.invID
LEFT JOIN `item-service` item ON item.itemID = i_o.itemID
LEFT JOIN person p ON p.PID=i.personID
LEFT JOIN shift s ON s.shiftID = i.shiftID
LEFT JOIN employee e ON e.empID = s.empID
WHERE i.shiftID = 97

left join table name dynmicly form the main query

I have a bills table with column customer_type and customer_id fields.
This customer_type tells if the customer is in the customers table or in the users table or in the suppliers table.
I need to create a query with left join according to customer_type.
select c.* from bills b
left join ***b.customer_type*** c on c.id = b.customer_id
You could join all three with necessary condition:
select c.*, u.*, s.* from bills b
left join customers c on c.id = b.customer_id and b.customer_type = 'customers'
left join users u on u.id = b.customer_id and b.customer_type = 'users'
left join suppliers s on s.id = b.customer_id and b.customer_type = 'suppliers'
Then you can take the data that is relevant from the result.
However if there are similar columns in these 3 tables you might want to restructure the database to only store one type of information in one place.

Fetching a price with INNER JOIN using 3 different variables

What I have been trying to achieve is to pull a price based on 3 different variables: brand_id, model_id, motor_id.
The design of the tables that I am working with:
The only issue is that when I add an INNER JOIN for databaseapp_lkp_prices I get a zero result set (fyi, there aren't any prices currently set so databaseapp_lkp_prices is an empty table)
I was expecting to see NULL in place of the price for the 48,000 records that exist when I don't add the databaseapp_lkp_prices INNER JOIN
My query is:
SELECT
a.brand,
b.model,
c.motor,
d.ecu_hardware_ver,
d.ecu_software_ver,
d.ecu_software_upg_ver,
d.ecu_brand,
d.ecu_type,
d.eprom,
d.eprom_desc,
d.`checksum`,
d.checksum16,
c.motor_hp * 1.2 AS motor_hp,
e.price,
c.motor_id,
c.model_id,
c.brand_id
FROM
databaseapp_brand AS a
INNER JOIN databaseapp_model AS b ON b.brand_id = a.brand_id
INNER JOIN databaseapp_motor AS c ON b.model_id = c.model_id
INNER JOIN databaseapp_ecu AS d ON d.motor_id = c.motor_id
INNER JOIN databaseapp_lkp_prices AS e ON c.brand_id = e.brand_id AND c.model_id = e.model_id AND c.motor_id = e.motor_id
ORDER BY
a.brand ASC,
b.model ASC
Anyone able to help me out with why I'm getting a zero result set when I try to look up the price.
Cheers!
Inner join requires match. No match no row. You should try LEFT JOIN instead of INNER JOIN for databaseapp_lkp_prices contribution.

Check id joining 3 tables

I have a MySQL JOIN query where 2 tables are joined to get the output
select distinct (a.error_type),a.links_id, a.crawl_cycle , b.* from $table a inner join crawler_error_type b on a.error_type = b.error_type where a.projects_id = '$pid' and b.error_priority_page_level='High'
Now I want to check if the value of the field error_type is present in the third table. If it is present then it shouldn't give me the resulted row.
Add the below:
LEFT OUTER JOIN third_table c ON c.error_type = a.error_type
and
WHERE c.error_type is null
LEFT OUTER JOIN will display all the records from a table joining on third_table. Since you do not want the record with matching error type from third_table, use WHERE c.error_type is null
You need to add one more INNER JOIN on third_table as:
SELECT DISTINCT a.error_type, a.links_id, a.crawl_cycle , b.*
FROM $table a
INNER JOIN crawler_error_type b
ON a.error_type = b.error_type
INNER JOIN third_table c
ON a.error_type = c.error_type
WHERE a.projects_id = '$pid' AND
b.error_priority_page_level='High'.
If I understand it correctly, you should just be able to inner join the third table. Inner joins will on show the record if they have records in the joining tables. If I am misunderstanding could you please elaborate. Thx
select distinct (a.error_type),a.links_id, a.crawl_cycle , b.*
from $table a
inner join crawler_error_type b on a.error_type = b.error_type
inner join some_table_3 c on c.error_type = a.error_type
where a.projects_id = '$pid' and b.error_priority_page_level='High'