SQL Join with SUM() - sql

I have two Tables
Product Details(About Product)
Sale Order Details(What Price is sold, quantity of products sold per order).
I am trying to do Join on Table 1 and Table 2 which should give the all the product details and sum(Quantity), Sum(Price)
Problem Facing: There are some products in Table 1 which are never sold, and those rows are missing in the result set, but I want details for all the rows in Table 1 with rows of Products never purchased should be NULL or 'o'
Query I am Using:
select
P.*,
ISNULL((sum([Q.Quantity])),0),
ISNULL((sum([Q.Price])),0)
From Table1 P
Left Outer Join Table2 Q on P.Product_ID = Q.Product_ID
Please help me with any suggestions that would work for me

How about this one:
select
P.Product_ID,
ISNULL(sum([Q.Quantity]),0),
ISNULL(sum([Q.Price]),0)
From Table1 P
Left Outer Join Table2 Q
on P.Product_ID = Q.Product_ID
group by
P.Product_Id

Related

Using MS Access SQL - how would I select the top 5 food items by group (restaurant) based on the number of orders?

Relationship Diagram
What I want to be able to do is return a query that shows the top 5 items/products on the menu for each of the 3 restaurants in the dataset. I've attached an example of the relationship diagram for some more context. The columns I would like to see in the query are:
RestaurantName
ItemName
NumberofOrders (alias column)
This is what I have at the moment but it doesn't work as expected for the top 5.
SELECT RestaurantName, ItemName, COUNT(Orders.OrderNumber) AS NumberofOrders
FROM ((((Restaurants INNER JOIN
Orders ON Restaurants.RestID = Orders.RestID) INNER JOIN
OrderDetails ON Orders.OrderNumber=OrderDetails.OrderNumber) INNER JOIN
Products ON OrderDetails.ItemID = Products.ItemID) INNER JOIN
FoodType ON Products.ProdTypeID = FoodType.ProdType)
WHERE ItemName IN
(SELECT TOP 5 ItemName
FROM Products
WHERE ItemName IS NOT NULL)
GROUP BY RestaurantName, ItemName
ORDER BY COUNT(Orders.OrderNumber) DESC;
This just repeats the same 5 items across all the restaurants. Any point in the right direction would be awesome.
EDIT 1:
Based on a response I got yesterday, I have made some amendments to the code. This the query is returning the full list, as though ignoring the top 5 in the subquery. I can see all the items are sorted by Total Orders (I have also changed the formula for this) Any ideas what I am doing wrong here?
SELECT RestaurantName, ItemName, SUM(Quantity)*COUNT(Orders.OrderNumber) AS TotalOrders
FROM ((((Restaurants INNER JOIN
Orders ON Restaurants.RestID = Orders.RestID) INNER JOIN
OrderDetails ON Orders.OrderNumber=OrderDetails.OrderNumber) INNER JOIN
Products ON OrderDetails.ItemID = Products.ItemID) INNER JOIN
FoodType ON Products.ProdTypeID = FoodType.ProdType)
WHERE ItemName IN
(SELECT TOP 5 p2.ItemName
FROM Products AS p2
WHERE p2.ItemName = Products.ItemName
GROUP BY p2.ItemName
ORDER BY COUNT(*) DESC)
GROUP BY RestaurantName, ItemName
ORDER BY RestaurantName, SUM(Quantity) DESC;
Thanks
You want a correlated subquery:
WHERE ItemName IN (SELECT TOP 5 p2.ItemName
FROM Products as p2
WHERE p2.RestaurantName = products.RestaurantName
GROUP BY p2.ItemName
ORDER BY COUNT(*) DESC
)
It seems really odd to me that a table called products would have a column called RestaurantName. But you claim that your query works and it has the same reference.
Your filter in the outer WHERE is only using the ItemName field. For your purpose it should contain both fields.
Like so:
SELECT
RestaurantName,
ItemName,
COUNT(Orders.OrderNumber) AS NumberofOrders
FROM Restaurants
INNER JOIN Orders ON Restaurants.RestID = Orders.RestID
INNER JOIN OrderDetails ON Orders.OrderNumber=OrderDetails.OrderNumber
INNER JOIN Products ON OrderDetails.ItemID = Products.ItemID
INNER JOIN FoodType ON Products.ProdTypeID = FoodType.ProdType
WHERE (RestaurantName, ItemName) IN
(SELECT TOP 5 RestaurantName, ItemName
FROM Products
WHERE RestaurantName IS NOT NULL)
GROUP BY RestaurantName, ItemName
ORDER BY COUNT(Orders.OrderNumber) DESC;

SQL Sumation from Different Tables

I would like some help on this matter.
I Have three tables.
Products Table,
Invoice Table,
Cash Table
Products Table has 2 Columns as follows (PID,BRAND)
Invoice Table has 2 columns as follows (PID,TOTALSALES)
Cash Table has 2 columns as follows (PID,TOTALSALES)
The PID's could have many different BRANDS.
for eg:
PID BRAND
1 TEST1
2 TEST2
3 TEST3
All the three tables are linked by the PID column.
i have many rows in the invoice and cash tables.
My problem is to Group the SUMMED values of the TOTALSALES in the INVOICE and CASH tables BRAND wise.
I tried using left joins but the summation value always increases when there are more than 2 table in the join.
Any help will be highly appreciated.
You can use union all and then aggregate the results from the two tables together:
select p.brand, sum(invoice_sales) as invoice_sales, sum(cash_sales) as cash_sales
from ((select pid, totalsales as invoice_sales, 0 as cash_sales
from invoice i
) union all
(select pid, 0, totalsales
from cash c
)
) ic join
product p
on ic.pid = p.id
group by p.brand;
summarise the data in the Invoice and Cash tables separately
SELECT
pr.BRAND, (ISNULL(Inv.TOTALSALES, 0.00) + ISNULL(Csh.TOTALSALES, 0.00)) TotalSales
FROM Products pr
LEFT JOIN (
SELECT
PID, SUM(TOTALSALES) TOTALSALES
FROM Invoice GROUP BY PID
) Inv ON Inv.PID = pr.PID
LEFT JOIN (
SELECT
PID, SUM(TOTALSALES) TOTALSALES
FROM Cash GROUP BY PID
) Csh ON Csh.PID = pr.PID
ORDER BY pr.BRAND
You need two separate sums for the results of joining the tables by PID values and you will need to group the records by BRAND
select sum(Invoice.TOTALSALES) as invoice_sales, sum(Cash.TOTALSALES) as cash_sales
from Products
join Invoice
on Products.PID = Invoice.PID
join Cash
on Products.PID = Cash.PID
group by Invoice.PID, Products.BRAND;
If you do not need to group by products, then just omit Invoice.PID from the group by.
another way to do it is by using subquerys
select p.*,
(select sum(i.TOTALSALES) from Invoice i where i.PID = p.PID) as TotalSalesInvoice,
(select sum(c.TOTALSALES) from Cash c where c.PID = p.PID) as TotalSalesCash
from Products p

Triple Table Join with Subtraction

I have 3 tables (production, sales, wastage)
All 3 tables have the columns: Product and Quantity
I need a query statement that will join all 3 tables in the following manner:production - sales - wastage Grouped by Product
Thanks in advance for the tips and tricks :)
Combine tables using left join, group by product and get total quantity by substracting values assuming that there can be no record for a given product within sales or wastage tables and then count them as 0.
select p.product, sum(p.quantity - coalesce(s.quantity,0) - coalesce(w.quantity,0)) as qty
from production p
left join sales s on p.product = s.product
left join wastage w on p.product = w.product
group by p.product
You can group each table individually and then [left] join them:
SELECT p.product, p_quantity - COALESCE(s_quantity, 0) - COALESCE(w_quantity, 0)
FROM (SELECT product, SUM(quantity) AS p_quantity
FROM production
GROUP BY product) p
LEFT JOIN (SELECT product, SUM(quantity) AS s_quantity
FROM sales
GROUP BY product) s ON p.product = s.product
LEFT JOIN (SELECT product, SUM(quantity) AS w_quantity
FROM wastage
GROUP BY product) w ON p.product = w.product

sql select count of multiple relationships with left join

I have a table for "branches", "orders" and "products. Each order and product are connected to a branch with branch_id. I need an sql statement to get a list of all branches with a field for how many orders and a field for how many products.
This works:
SELECT b.*, COUNT(o.id) AS orderCount FROM branches b
LEFT JOIN orders o ON (o.branch_id = b.id) GROUP BY b.id
but it only gets the amount of orders, not products.
If I change it to add amount of products, the amounts are wrong because it's getting amount of orders * amount of products.
How can I get the amount of both the orders and the products in the same SQL statement?
Something like this should work (on sql server at least - you didn't specify your engine).
SELECT
b.id
,COUNT(distinct o.id) AS orderCount
,COUNT(distinct p.id) AS productCount
FROM branches b
LEFT JOIN orders o
ON (o.branch_id = b.id)
left join products p
on p.product_id=b.id)
GROUP BY
b.id
Please try:
select
*,
(select COUNT(*) from Orders o where o.branch_id=b.id) OrderCount,
(select COUNT(*) from Products p where o.branch_id=p.id) ProductCount
From
branches b

SQL Grouping using left join

I have 2 tables with related data. One table is for products and the other price. In the price table one product may appear several times. How can I return the result by grouping.
Below is my Query but the output is not with Group
SELECT distinct
p.Product,
p.Qty,
MAX(pr.netprice)
FROM Products p
LEFT OUTER JOIN Price pr ON p.Product=pr.Product
WHERE p.brand=''
GROUP BY p.Product, p.Qty
You should probably leave the Qty out of the group by, like this:
SELECT p.Product,
MAX(pr.netprice)
FROM Products p
LEFT OUTER JOIN Price pr ON p.Product=pr.Product
WHERE p.brand=''
GROUP BY p.Product