Trying to sum part of the rows - sql

So I have three tables
Orders:
CustomerID,OrderID
Order Details;
OrderID,ProductId,UnitPrice,Quantity,Discount
And Products:
ProductID,ProductName
And I need to combine these 2 tables and create this one:
[Orderd Details].CustomersID,Products.ProductName,FORMULA
Formula is how much money people spent money on this product. So I think I have to sum UnitPrice* Quantity*(1-Discount) from every order for this product.
Sadly I have no idea how should I do it. The best I did is:
SELECT o.CustomerID,p.ProductName,SUM(od.Quantity*od.UnitPrice*(1-od.Discount)) as 'SKZ'
FROM Customers as c, Orders as o,[Order Details] as od,Products as p
WHERE (o.OrderID=od.OrderID AND p.ProductID=od.ProductID)
GROUP BY od.ProductID ORDER BY o.CustomerID;
But it doesn't work.

First, learn explicit JOIN syntax. Simple rule: Never use commas in the FROM clause.
Second, you should include all non-aggregated columns in the GROUP BY:
SELECT o.CustomerID, p.ProductName,
SUM(od.Quantity * od.UnitPrice * (1 - od.Discount)) as SKZ
FROM Orders as o JOIN
[Order Details] od
ON o.OrderID = od.OrderID JOIN
Products p
ON p.ProductID = od.ProductID
GROUP BY o.CustomerID, p.ProductName
ORDER BY o.CustomerID;

Related

SQL Subqueries - Exists – Any - All

I have a problem facing this subquery SQL exercice,using Northwind DB:
**16.
From order number 10251 show employee's name,company's name, order's
date,name of each product,quantity,unit price and
final price (= unitprice * quantity – unitprice*quantity*discount)
**
The following is my attempt of a solution, each of the subqueries work fine by their own,giving the expected result but it fails when combined together in the same query
select
(select FirstName from Employees where EmployeeID=Orders.EmployeeID)as 'Name',
(select Customers.CompanyName from Customers where Customers.CustomerID = Orders.CustomerID)'Company name' ,
(select Products.ProductName,Products.UnitPrice,
[Order Details].Quantity,
(Products.UnitPrice*[Order Details].Quantity-Products.UnitPrice*[Order Details].Quantity*[Order Details].Discount)
AS 'Final Price' from Products
INNER JOIN [Order Details] on Products.ProductID= [Order Details].ProductID
WHERE [Order Details].OrderID=10251),
Orders.OrderDate
from Orders
where OrderID=10251
I believe your query was failing because the third subquery (for Final Price) was returning a relation, as opposed to a scalar value.
I've re-written the query in a form that opts for joins rather than subqueries. Subqueries can be useful but I think using joins here makes the query little easier to read and work with.
select firstName as Name,
C.companyName as CompanyName,
P.UnitPrice * OD.Quantity
- (P.UnitPrice * OD.Quantity * OD.Discount)
as FinalPrice
from Orders as O
left join Employees as E
on E.employeeId = O.employeeId
left join Customers as C
on C.customerId = O.customerId
left join [Order Details] as OD
on OD.orderId = O.orderId
left join Products as P
on P.productId = OD.produtId

I'm trying to use an aggregate function in order to consolidate the data but I'm not sure what I'm doing wrong

I have to find the total price per unit quantity and price. How can I make this work in a way where I can consolidate all the orders from one person with the total price that they ordered?
I'm new to SQL and not sure where to start to fix this.
SELECT DISTINCT Orders.OrderID, Customers.ContactName, Orders.OrderDate, [Order
Details].Quantity * [Order Details].UnitPrice
FROM Orders, Customers, [Order Details]
WHERE Orders.CustomerID = Customers.CustomerID
AND Orders.ShipCountry = 'Spain'
Three important things I can advice you to do:
Use explicit JOIN syntax: don't write your tables separately with comma, use explicit JOINs against them so it forces you to write their link at that moment and it's easier to read later. Your attempt was missing a link between the orders and the order details, probably making a lot of duplicates on your results.
Aggregates needs a GROUP BY. Whenever you want to apply aggregate functions like SUM, MAX, COUNT, you will (mostly) need a set of columns you want to group together. These columns go in the GROUP BY clause.
Don't use DISTINCT if you are unsure of the results you are getting. It seems that you used DISTINCT to cover up the missing link between orders and order details, so it just list uniques instead of the actual data your select is returning.
SELECT
C.CustomerID,
C.ContactName,
O.OrderID,
O.OrderDate,
TotalPrice = SUM(D.Quantity * D.UnitPrice)
FROM
Orders AS O
INNER JOIN Customers AS C ON O.CustomerID = C.CustomerID
INNER JOIN [Order Details] AS D ON O.OrderID = D.OrderID
WHERE
O.ShipCountry = 'Spain'
GROUP BY
C.CustomerID,
C.ContactName,
O.OrderID,
O.OrderDate
I think you want to do the join like this...
SELECT DISTINCT Orders.OrderID, Customers.ContactName, Orders.OrderDate,
[Order Details].Quantity * [Order Details].UnitPrice FROM Orders left join
Customers on Orders.CustomerID = Customers.CustomerID left join [Order
Details] on Orders.CustomerID = [Order Details].CustomerID where
Orders.ShipCountry = 'Spain'

sql use aggregate function that counts a unique value with group by using inner joins

I searched and found similar questions online but not my particular one, they all use where or having clause.If theres one similar to mine please link it. It's a 2 part question and I have the first one done. Thank you in advance.
Okay so heres the question, part 1
"Find by customer, the total cost and the total discounted cost for each product on the order ?".
It also asks to use inner joins to find the customer and order it a specific way. Below is the answer.
SELECT
C.companyname, O.orderid, O.orderdate, P.productname,
OD.orderid, OD.unitprice, OD.qty, OD.discount,
(OD.unitprice * OD.qty - (OD.qty * OD.discount)) AS TotalCost,
(OD.qty * OD.discount) AS TotalDiscountedCost
FROM
Sales.Customers AS C
INNER JOIN
Sales.Orders AS O ON C.custid = O.custid
INNER JOIN
Sales.OrderDetails OD ON O.orderid = OD.orderid
INNER JOIN
Production.Products as P ON OD.productid = P.productid
ORDER BY
C.companyname, O.orderdate;
Now the second question is to
follow up and resume the first one by "customer and the order date year, the total cost and the total discounted cost on the order ?". It also asks for this, "Project following columns in the select clause as.
GroupByColumns.companyname
GroupByColumns.OrderdateYear
AggregationColumns.CountNumberOfIndividualOrders
AggregationColumns.CountNumberOfProductsOrders
AggregationColumns.TotalCost
AggregationColumns.TotalDiscountedCost
Finally to order by company name and orderdateYear( which are groups). Where im stuck is how to count the specific orders of qty that equal 1 as an aggregate function in the SELECT clause. I know it has to use the aggregate function COUNT because of the GROUP BY, just don't know how to. This is what I have.
SELECT
C.companyname, YEAR(O.orderdate) AS orderyear,OD.qty,
-- Where in the count function or if theres another way do I count all the
--single orders
--COUNT(OD.qty) AS indiviualorders,
(OD.unitprice * OD.qty - (OD.qty * OD.discount)) AS TotalCost,
(OD.qty * OD.discount) AS TotalDiscountedCost
FROM
Sales.Customers AS C
INNER JOIN
Sales.Orders AS O ON C.custid = O.custid
INNER JOIN
Sales.OrderDetails OD ON O.orderid = OD.orderid
INNER JOIN
Production.Products as P ON OD.productid = P.productid
GROUP BY
C.companyname, YEAR(O.orderdate)
ORDER BY
C.companyname, O.orderdate;
You case use a case statement inside a sum
SUM(CASE WHEN <xyz> THEN 1 ELSE 0 END)
But for the count of unique orders, use SELECT(DISTINCT ) on a key that is unique in the order table
SELECT COUNT(DISTINCT O.OrderID) As DistinctOrders FROM Table

SQL Server : How to Select Sum Amount Spent for the Most Expensive Item by a Customer - Northwind DB

Actually question tells all; Lots of customers has many orders with for many items; I'm trying to display the total amount spent for the most expensive item ordered by that customers through the all orders given by that customer. I'm using Northwind DB and tables like Customers, Orders, Order Details, Products. I've the query below, I've tried to limit it by an aggregate function but SQL does not allow it on where clause. Any help?
select
p.ProductName,
c.ContactName,
od.ProductID,
MAX(od.UnitPrice)
SUM(od.UnitPrice*od.Quantity) as Total
from
Customers c
join
Orders o ON c.CustomerID = o.CustomerID
join
[Order Details] od on od.OrderID = o.OrderID
join
Products p on od.ProductID = p.ProductID
where
c.CustomerID in
group by
c.ContactName, p.ProductName, od.Quantity, od.ProductID
order by
MAX(od.UnitPrice) desc
I think the easiest way to solve this is by using a window function to get the highest priced product. The following query uses row_number() for this purpose:
select p.ProductName, c.ContactName, od.ProductID,
MAX(od.UnitPrice)
SUM(od.UnitPrice*od.Quantity) as Total
from Customers c join
(select od.*, o.CustomerId,
row_number() over (partition by o.CustomerId
order by od.UnitPrice desc) as seqnum
from [Order Details] od join
Orders o
on od.OrderId = o.OrderId
) od
on od.CustomerId = c.CustomerId and seqnum = 1 join
Products p
on od.ProductID = p.ProductID
group by c.ContactName, p.ProductName, od.ProductID
order by MAX(od.UnitPrice) desc;
Note that the joins have been rearranged a bit. You need the customer id to define the highest priced product in the subquery, so the subquery has the join to orders. You don't need the join in the outer query.

SQL query with w3schools db

I should have asked multiple questions in my other post. Thanks to all who have helped, I am now stuck on another one..
Using the w3schools db, List SupplierID, SupplierName and ItemSupplied (count of number of items supplied by a supplier), sort the list first by number of items supplied (descending) and then by supplier name (ascending)
SELECT supplierid,
suppliername,
p.productname,
Count(s.supplierid) AS itemssupplied
FROM [Suppliers] AS s
INNER JOIN [Products] AS p
ON p.supplierid = s.supplierid
GROUP BY p.productid,
p.productname
ORDER BY Count (p.productid, p.productname) DESC
order BY s.suppliername
It's giving me an error, then again I am ordering by multiple ones. I think there's something I am not quite understanding here.
My other question is
List customers for each category and the total of order placed by that customer in a given category. In the query show three columnm: CategoryName, CustomerName, and TotalOrders (which is price * quantity for orders for a given customer in a given category). Sort this data in descending order by TotalOrders.
SELECT cg.CategoryName,
c.CustomerName,
Sum(p.Price * od.Quantity) AS TotalOrders
FROM [products] AS p
INNER JOIN [orderdetails] AS od
ON od.ProductID = p.ProductID
INNER JOIN [orders] AS o
ON o.OrderID = od.OrderID
INNER JOIN [customers] AS c
ON c.customerID = o.CustomerID
INNER JOIN [categories] AS cg
ON cg.CategoryID = p.CategoryID
GROUP BY c.CustomerName
ORDER BY TotalOrders DESC
Can someone please check if my query is correct? Thank you once again!
Question 1
You are really close but you only need to state ORDER BY once (also make sure to include all shown fields in your GROUP BY unless you are aggregating them):
SELECT SupplierID, SupplierName, p.ProductName, count(s.SupplierID) AS ItemsSupplied
FROM [Suppliers] AS s
INNER JOIN [Products] AS p ON p.SupplierID = s.SupplierID
GROUP BY p.ProductID, p.ProductName, SupplierID, SupplierName -- Added SupplierID, SupplierName
ORDER BY COUNT (p.productID, p.ProductName) DESC, s.SupplierName
Notice that you just place multiple sorts on the same line with a comma separating them.
Question 2
You're almost there but you need to group by any field that is not being aggregated. So in order not to get a parsing error, I added the cg.CategoryName to the GROUP BY line.
SELECT cg.CategoryName, c.CustomerName, Sum(p.Price*od.Quantity) AS TotalOrders
FROM [Products] AS p
INNER JOIN [OrderDetails] AS od ON od.ProductID = p.ProductID
INNER JOIN [Orders] AS o ON o.OrderID = od.OrderID
INNER JOIN [Customers] AS c ON c.customerID = o.CustomerID
INNER JOIN [Categories] AS cg ON cg.CategoryID = p.CategoryID
GROUP BY c.CustomerName, cg.CategoryName --Added CategoryName
ORDER BY TotalOrders DESC
You have several problems with the first query:
You're grouping by ProductID and ProductName even though you want the number of items supplied by a supplier, which means that you want to group by SupplierID and SupplierName.
You're supplying too many arguments to the COUNT function, which takes a single column name or *.
You've included a ProductName column in your results, which is not called for.
You need to ORDER BY both the number of products supplied and the SupplierName.
With those points in mind:
SELECT
s.SupplierID,
s.SupplierName,
COUNT(p.ProductID) AS ItemsSupplied
FROM
[Suppliers] AS s
INNER JOIN [Products] AS p ON p.SupplierID = s.SupplierID
GROUP BY
s.SupplierID, s.SupplierName
ORDER BY
ItemsSupplied DESC,
s.SupplierName ASC
Your second query is quite close, you're just missing one point, which is that you're looking for total of order placed by that customer in a given category. This means that in addition to grouping by c.CustomerName, you need to group by cg.CategoryID:
SELECT
cg.CategoryName,
c.CustomerName,
SUM(p.Price*od.Quantity) AS TotalOrders
FROM
[Products] AS p
INNER JOIN [OrderDetails] AS od ON od.ProductID = p.ProductID
INNER JOIN [Orders] AS o ON o.OrderID = od.OrderID
INNER JOIN [Customers] AS c ON c.customerID = o.CustomerID
INNER JOIN [Categories] AS cg ON cg.CategoryID = p.CategoryID
GROUP BY
c.CustomerName, cg.CategoryID
ORDER BY
TotalOrders DESC
The first one has two order by clauses
ORDER BY COUNT (p.productID, p.ProductName) DESC
and
ORDER BY s.SupplierName
also some databases will complain when order by columns for queries using group by are not included in the selected columns