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
Related
I'm new to MySQL. I created a view as orders to get order data.
I want to return all the order information but it only returns the orders where the discount has been applied. My code is below.
CREATE VIEW orders
AS SELECT order_number, staff_name, manufacturer, o.product_id, product_name, quantity,
o.delivery_address, discount_percentage, price*quantity AS Total
FROM order_detail AS o INNER JOIN delivery AS d ON d.delivery_number = o.delivery_number
INNER JOIN staff AS s ON d.staff_id = s.staff_id
INNER JOIN vehicle AS v ON s.staff_id = v.staff_id
INNER JOIN product AS p ON o.product_id = p.product_id
INNER JOIN discount AS e ON e.discount_name = o.disocunt_name;
It gets an answer like
While that answer is correct I want all the orders to return not just orders with discounts. Please Help.
Use left joins. Start with the table you want to keep all of -- orders_detail:
SELECT o.order_number, staff_name, manufacturer, o.product_id, product_name, quantity,
o.delivery_address, discount_percentage, price*quantity AS Total
FROM order_detail o LEFT JOIN
delivery d
ON d.delivery_number = o.delivery_number LEFT JOIN
staff s
ON d.staff_id = s.staff_id LEFT JOIN
vehicle v
ON s.staff_id = v.staff_id LEFT JOIN
product p
ON o.product_id = p.product_id LEFT JOIN
discount e
ON e.discount_name = o.discount_name;
Note: You should qualify all column references.
Hey I am trying to join 4 tables in sql, with an left join and an inner join.
Hospital table
HospitalID| Name| Province| Email|
Order table
OrderID| HospitalID| StaffID| DeliverID| Date| Time
Item table
ItemID| Type| Name| Quantity| Expiry_Date
OrderItem table
OrderItemID| OrderID| ItemID| Quantity
I attempted executing the following SQL query but I am getting error message and I don't know what I'm doing wrong.
SELECT Hospital.Name, Item.Type, OrderItem.Quantity
FROM Hospital
LEFT JOIN [Order]
ON Hospital.HospitalID=[Order].HospitalID
INNER JOIN (SELECT Item.Type
FROM Item
GROUP BY Item.Type)
OrderItem ON Item.ItemID = OrderItem.ItemID
;
There are few mistakes in the query, the syntax using [Order] is invalid in mysql, and then you need an alias for the inner query. Also OrderItem needs to be joined first with Order. Further more no need to use use subquery for join since you are not doing any aggregate part to get the data from Item. In mysql the query will look like below.
SELECT
h.Name,
i.Type,
oi.Quantity
FROM Hospital h
LEFT JOIN `Order` o ON o.HospitalID = h.HospitalID
INNER JOIN OrderItem oi on oi.OrderID = o.OrderID
INNER JOIN Item i
on i.ItemID = oi.ItemID ;
Note that Order is a reserved word so you need to backtick it as done in the query above
you can use below simple query-
SELECT
hosp.Name,
itm.Type,
oi.Quantity
FROM Hospital hosp
JOIN `Order` ord ON ord.HospitalID = hosp.HospitalID
JOIN OrderItem oi on oi.OrderID = ord.OrderID
JOIN Item itm on itm.ItemID = oi.ItemID;
If there is chance that you want to show all hospital name even without its details in other tables like type, quantity etc. then you can use of left join-
SELECT
hosp.Name,
itm.Type,
oi.Quantity
FROM Hospital hosp
LEFT JOIN `Order` ord ON ord.HospitalID = hosp.HospitalID
LEFT JOIN OrderItem oi on oi.OrderID = ord.OrderID
LEFT JOIN Item itm on itm.ItemID = oi.ItemID;
I have following:
Tables(field names)
Active( activeID, activeName)
ActiveCategories(activeID, categoryID)
Categories(categoryID,categoryName)
I wish to query such that the result fetches Left Join of Active on ActiveCategories but instead of CategoryID [from ActiveCategories] Integer it should display corresponding categoryName [ from Categories].
Till now I have managed to display integer but not the corresponding name.
select a.activeID, a.activeName, c.categoryName
from Active a
left outer join ActiveCategories b on a.activeID = b.activeID
left outer join Categories c on b.categoryID = c.categoryID
Try:
select a.activeID, a.activeName, d.categoryName
from Active a
left join (select b.activeID activeID, c.categoryName CategoryName
from ActiveCategories b
left join Categories c on b.categoryID = c.categoryID) d
on a.activeID = d.activeID
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.
I'm having a real mind blank - This code selects rows quite nicely apart from those entries where I change st.station_id from a value of '1' to a different (but still valid) number but where there are no entries for that station_id in either the station_owner_map table, the organisation table or the cap_gen_data_table. I basically need to amend my sql to ignore any table where there are no entries.
Select st.station_id, st.station_name , st.st_town, st.st_state, c1.country_name, o1.organisation_name, som1.equity, st.river_basin, st.cost, st.cost_ref, st.comm_year,cg1.caporgen, ht1.hydro_name, cg1.value, srs1.srs_description, cg1.ref_year
FROM station st
inner join station_country_map scm1 on st.station_id = scm1.station_id
inner join country c1 on scm1.country_id = c1.country_id
inner join station_owner_map som1 on st.station_id = som1.station_id
inner join organisation o1 on som1.owner_id = o1.org_id
inner join cap_gen_data cg1 on st.station_id = cg1.station_id
inner join value_lookup vl1 on cg1.caporgen = vl1.id
inner join hydro_type ht1 on cg1.hydro_type_id = ht1.type_id
inner join station_record_status srs1 on cg1.capacity_status = srs1.st_rec_stat_id
where st.station_id = 1
It's caused by your inner joins. Inner join means there has to be a value in both tables for the record to show up in the result set.
Use left join instead, then only the table 'on the left' has to have a value.
Use left join on tables where the value may not be present.
If you have two tables A and B an inner join will only return the rows from A where the join condition is met. A left join will return all rows from A regardless of if the join condition is satisfied. Columns in the select statement associated with B will be null when a left join is used.
I have only added the left join to the tables you have indicated. If other tables may not satisfy the join condition change the join type from inner to left.
Select st.station_id, st.station_name , st.st_town, st.st_state, c1.country_name, o1.organisation_name, som1.equity, st.river_basin, st.cost, st.cost_ref, st.comm_year,cg1.caporgen, ht1.hydro_name, cg1.value, srs1.srs_description, cg1.ref_year
FROM station st
inner join station_country_map scm1 on st.station_id = scm1.station_id
inner join country c1 on scm1.country_id = c1.country_id
left join station_owner_map som1 on st.station_id = som1.station_id
left join organisation o1 on som1.owner_id = o1.org_id
left join cap_gen_data cg1 on st.station_id = cg1.station_id
inner join value_lookup vl1 on cg1.caporgen = vl1.id
inner join hydro_type ht1 on cg1.hydro_type_id = ht1.type_id
inner join station_record_status srs1 on cg1.capacity_status = srs1.st_rec_stat_id
where st.station_id = 1