SQL Joint and Group two tables with SUM function - sql-server

SO i have two tables:
Products
Product ID | Quantity
OrdersLines
Product ID | Amount (multiple lines with same ID)
I want to join two tables. Result should be - Product ID (Group by), Quantity and Sum of all amounts from OrdersLines table.
I got this so far:
SELECT P.ProductID, P.Quantity, SUM(OL.Amount)
FROM atbl_Sales_Products AS P
LEFT JOIN atbl_Sales_OrdersLines AS OL ON OL.ProductID = P.ProductID
GROUP BY P.ProductID
This produces error:
Column 'atbl_Sales_Products.Quantity' is invalid in the select list
because it is not contained in either an aggregate function or the
GROUP BY clause.
Thanks for help!

Well, there are two ways to write this depending on what you want
Adding the Quantity to the aggregate...
SELECT
P.ProductID,
SUM(P.Quantity),
SUM(OL.Amount)
FROM atbl_Sales_Products AS P
LEFT JOIN atbl_Sales_OrdersLines AS OL ON OL.ProductID = P.ProductID
GROUP BY P.ProductID
Adding the quantity to the grouping
SELECT
P.ProductID,
P.Quantity,
SUM(OL.Amount)
FROM atbl_Sales_Products AS P
LEFT JOIN atbl_Sales_OrdersLines AS OL ON OL.ProductID = P.ProductID
GROUP BY P.ProductID, P.Quantity
--based on comment
HAVING SUM(OL.Amount) > P.Quantity

Related

Count relationed items

I have a query like this:
SELECT
*
FROM Product.Stock AS PS
INNER JOIN Product.Product AS P ON PS.ProductId = P.ProductId
INNER JOIN Product.ProductDetail AS PD ON P.ProductId = PD.ProductId
INNER JOIN Product.ProductSize AS PSI ON P.ProductId = PSI.ProductId
I want to know how many ProductsId with same SizeId I have, for example:
in this case I have two products with same ProductId and SizeId, so I wish get: 2 because I have 2 products with sizeId 1
ProductId comes from table: Product.Product
SizeId comes from table: Product.ProductSize
How can I achieve it? Regards
SELECT
PSI.SizeId, COUNT(DISTINCT P.ProductId)
FROM Product.Stock AS PS
INNER JOIN Product.Product AS P ON PS.ProductId = P.ProductId
INNER JOIN Product.ProductDetail AS PD ON P.ProductId = PD.ProductId
INNER JOIN Product.ProductSize AS PSI ON P.ProductId = PSI.ProductId
GROUP BY PSI.SizeId
I'm assuming that the SizeId column is in the Product.ProductSize table.
Agree with #Jack's answer, still I think joins seem to be redundant here.
SELECT
SizeId, COUNT(DISTINCT ProductId)
FROM Product.ProductSize
GROUP BY SizeId
Use Having Count in order to just show sizes with multiple products and no need for inner joins, since you already have all the fields in one table:
SELECT SizeId, COUNT(Distinct ProductId)
FROM Product.ProductSize
GROUP BY SizeId
Having Count(Distinct ProductId)> 1

Use Count() with self join in SQL Server

I'm working with the northwind database and my exercise is:
Which suppliers offer two products in the same category? Show company name, category and the both product names
My code:
SELECT DISTINCT
c.CategoryID, s.CompanyName, p1.ProductName, p2.ProductName
FROM
Suppliers s
INNER JOIN
Products p1 ON s.SupplierID = p1.SupplierID
INNER JOIN
Products p2 ON p1.CategoryID = p2.CategoryID
AND p1.ProductID <> p2.ProductID
INNER JOIN
Categories c ON p2.CategoryID = c.CategoryID
GROUP BY
c.CategoryID,s.CompanyName, p1.ProductName, p2.ProductName`
How can I filter that with COUNT() I tried to do it with HAVING but I failed.
I'll appreciate some help, which bringing me back on the right way.
Building on Gordon's answer the code below will get all the data you need. If you absolutely have to have both products in the same row, you can use pivot:
select s.CompanyName
,p.ProductName
from Suppliers s
-- This join filters your Suppliers table to only those with two Products in the same Category
inner join (select SupplierID
,CategoryID
from Products
group by SupplierID
,CategoryID
having count(1) = 2
) pc
on(s.SupplierID = pc.SupplierID)
-- This join returns the two products in the Category returned in the join above.
inner join Products p
on(s.SupplierID = p.SupplierID
and pc.CategoryID = p.CategoryID
)
You can get the list of suppliers/categories with exactly two products using a query like this:
select supplierId, categoryId
from products
group by supplierId, categoryId
having count(*) = 2;
Then, write a query to show the supplier and products names, and use the above to filter the results from that query. You can use either exists or an additional join.

SQL Sum() Query error

Actual Data
using these queries:
Select P.productid, Sum(pr.quantity) AS PQuantity from Products p
join purchases pr on pr.Productid = p.productid
group by p.productid;
Select P.productid, Sum(s.quantity) AS SQuantity from Products p
join Sales s on s.Productid = p.productid
group by p.productid;
This is the content in my tables (Purchases and Sales), the one on the right is the Sum with group by:
Problem:
select p.productid, sum(pr.quantity) as PQuantity, sum(s.quantity) as SQuantity
from products p
join sales s on p.productid = s.productid
join purchases pr on p.productid = pr.productid
group by p.productid
But the problem arises when I join three tables:
products
purchases
sales
You'll have to sum the figures before joining, something like this:
select isnull(P.productid, S.productid), P.PQuantity, S.SQuantity
from
(
Select P.productid, Sum(pr.quantity) AS PQuantity from Products p
join purchases pr on pr.Productid = p.productid
group by p.productid
) P
full outer join
(
Select P.productid, Sum(s.quantity) AS SQuantity from Products p
join Sales s on s.Productid = p.productid
group by p.productid
) S on S.productid = P.productid

my query doesn't work as expected

SELECT Product.ProductName
,SUM(Purchase.Value) AS TotalPurchase
,SUM(Sales.Value) AS TotalSales
,((TotalPurchase) - (TotalSales)) AS ProductAvailability
FROM Product
INNER JOIN Purchase ON Product.ProductID = Purchase.ProductID
INNER JOIN Sales ON Product.ProductID = Sales.ProductID
GROUP BY Product.ProductName
I have 3 Table Product - Sales - Purchase
and i want Show product name total sales each product ,total purchase of each
product And how many of those product still unsold
SELECT Product.ProductName
,SUM(Purchase.Value) AS TotalPurchase
,ISNULL(SUM(Sales.Value),0) AS TotalSales
,(SUM(Purchase.Value) - ISNULL(SUM(Sales.Value),0)) AS ProductAvailability
FROM Product
LEFT JOIN Purchase ON Product.ProductID = Purchase.ProductID
LEFT JOIN Sales ON Product.ProductID = Sales.ProductID
GROUP BY Product.ProductName
Since you also want to show the unsold products , there will be no data for them products in the sales table, hence you need a LEFT JOIN here not an INNER JOIN.
Also the columns TotalPurchase and TotalSales are available to be called in the query they are being calculated , hence use a sub-query to manipulate these columns or use the expression itself.
After 5 Hours OF playing With Query I FOUND THE ANSWER
SELECT PN.ProductName,TotalPurchase ,TotalSales,TotalPurchase-TotalSales AS ProductAvailability
FROM
((SELECT SUM(Purchase.Value) AS TotalPurchase,Purchase.ProductID FROM Purchase GROUP BY Purchase.ProductID ) AS TP
INNER JOIN
(SELECT SUM(Sales.Value) AS TotalSales,Sales.ProductID FROM Sales GROUP BY Sales.ProductID ) AS TS
ON tp.ProductID=TS.ProductID
INNER JOIN
(SELECT Product.ProductName,Product.ProductID FROM Product GROUP BY Product.ProductName,ProductID) AS PN ON PN.ProductID=TS.ProductID
)

How do you select multiple columns from multiple tables along with total cost?

I have four tables, but for this I only need three tables, and I want to display the customerid, orderid, productid, quantity and the total cost which isn't in any table but need to calculate? so far I have managed to get it to display total cost for one order with the order id, but I want it to display all the columns mentioned above
Order:
order_id(primary key)
customer_id( foreign key)
orderline:
orderid(fk) + productid(fk) (pk)
quantity
product:
productid(pk)
price
What I have done is
select orderid, sum(rowcost) as totalcost
from (select o.quantity, o.productid, o.orderid, os.customerid, p.price,
(o.quantity * p.price) as rowcost
from orderline o
inner join order os
on o.orderid = os.orderid
inner join product p
on p.productid = o.productid
where productid = 123)
group by orderid;
Now I want it to display all the orderids along with the productid, customerid, totalcost, orderid and quantity. The list should follow customerid order.
How would I do this?
when I add more variables in the select, it gives me errors. I have tried many ways, none of them worked.
do you mean you want something like this:
select o.quantity, o.productid, o.orderid, os.customerid, p.price,
(o.quantity * p.price) as rowcost,
sum(o.quantity * p.price) over (partition by os.customerid) as totalcost
from orderline o
inner join order os
on o.orderid = os.orderid
inner join product p
on p.productid = o.productid
where p.productid = 123
or this, to keep the sum correct if you wanted to filter afterwards on a product
select *
from (select o.quantity, o.productid, o.orderid, os.customerid, p.price,
(o.quantity * p.price) as rowcost,
sum(o.quantity * p.price) over (partition by os.customerid) as totalcost
from orderline o
inner join order os
on o.orderid = os.orderid
inner join product p
on p.productid = o.productid)
where productid = 123--or just remove this where clause
fiddle: http://sqlfiddle.com/#!4/3103d/1

Resources