SQL sum of order value from joining two tables - sql

I want to get the sum of sales of every order, along with customer and employee details from another table
Order Details table
OrderID ProductID UnitPrice Quantity Discount
10248 11 10 1 0
10248 42 20 2 0
10248 72 20 3 0
10249 14 10 1 0
10249 51 40 2 0
Orders table
OrderID CustomerName EmployeeName
10248 C1 E1
10249 C2 E2
Desired result
orderid sales Customer Employee
10248 110 C1 E1
10249 90 C2 E2
So I need total sum of sales for each order (e.g. 10248 order has sales 10*1 + 20*2 + 20*3 = 10+40+60=110) and corresponding employee name and customer name
Query tried
select od.orderid, Unitprice * Quantity as sales
group by od.orderid
From [Order Details] od
inner join orders o on od.orderid = o.orderid
Error:
Incorrect syntax near the keyword 'From'.

You need to aggregate by order, and then take the sum of the sales per order:
SELECT
od.orderid,
SUM(Unitprice * Quantity) AS sales
FROM [Order Details] od
INNER JOIN orders o
ON od.orderid = o.orderid
GROUP BY
od.orderid;

Try the following, you are having a group by before from. Also you do not need to do group by if you are using no aggregation instead you can use distinct.
select
od.orderid,
sum(Unitprice * Quantity) as sales
From [Order Details] od
inner join orders o on od.orderid=o.orderid
group by
od.orderid

FROM belongs before GROUP BY.
select od.orderid, unitprice * quantity as sales
from [Order Details] od
group by od.orderid;
With the order information joined:
select o.orderid, od.sales, o.customername, o.employeename
from orders o
join
(
select orderid, unitprice * quantity as sales
from [Order Details]
group by orderid
) od on od.orderid = o.orderid
order by o.orderid;

Use SUM() in conjuction with GROUP BY. I am incapable of testing but code like this should work on most SQL versions.
SELECT
od.orderid,
SUM(od.Unitprice * od.Quantity) as sales,
ot.CustomerName,
ot.EmployeeName
FROM od
INNER JOIN ot ON od.orderid=ot.orderid;
GROUP BY od.orderid;
You should be able to adapt the script to your database.

Related

multiple two column values with grouping by a column

I've two tables tblOrder and tblOrderDetails. I want to get order no, total price per order (Quantity*UnitCost) and OrderDate as given below.
Order No
Total
OrderDate
ORD 1
3000
01/01/2021
ORD 2
2750
01/03/2021
What I've tried is giving me quantity is not a part of aggregate function.
SELECT tblOrder.OrderNo, tblOrderDetails.UnitCost*tblOrderDetails.Quantity AS Total, OrderDate
FROM tblOrderDetails INNER JOIN tblOrder ON tblOrderDetails.OrderId = tblOrder .OrderId
GROUP BY tblOrder.OrderNo;
Table structures and data
Table tblOrder:
OrderId
OrderNo
OrderDate
1
ORD 1
01/01/2021
2
ORD 2
01/03/2021
Table tblOrderDetails:
OrderDetailId
Quantity
UnitCost
OrderId
1
100
30
1
2
50
40
2
2
10
15
2
2
20
30
2
select o.OrderNo
,od.total
,o.OrderDate
from
(
select OrderId
,sum(Quantity*UnitCost) as total
from tblOrderDetails
group by OrderId
) od join tblOrder o on o.OrderId = od.OrderId
OrderNo
total
OrderDate
ORD 1
3000
2021-01-01
ORD 2
2750
2021-01-03
Fiddle
Your requirements are not 100% clear, but maybe, you can just do this, without any subquery:
SELECT tblOrder.OrderNo,
SUM(tblOrderDetails.UnitCost*tblOrderDetails.Quantity) AS Total,
OrderDate
FROM tblOrderDetails
INNER JOIN tblOrder ON tblOrderDetails.OrderId = tblOrder.OrderId
GROUP BY tblOrder.OrderNo,OrderDate;
To see the difference to Danny's answer - which might also be fine - have a look here: db<>fiddle

SQL get total amount of Column with group by?

Below you can see my SQL query
select c.email_address,o.order_id as "Number of Orders",
((oi.item_price-oi.discount_amount)*oi.quantity) as "Total amount"
from customers c
inner join orders o on c.customer_id=o.customer_id
inner join order_items oi on o.order_id=oi.order_id
From that, I can get output like below
Email Orders_id Amount
allan#yahoo.com 1 839.3
barryz#gmail.com 2 303.79
allan#yahoo.com 3 1208.16
allan#yahoo.com 3 253.15
chrisb#gmail.com 4 1678.6
david#hotmail.com 5 299
erinv#gmail.com 6 299
frank#gmail.com 7 489.3
frank#gmail.com 7 559.9
frank#gmail.com 7 489.99
garyz#yahoo.com 8 679.99
david#hotmail.com 9 489.3
But I want to customize it like below
Email Number of Orders Total Amount
allan#yahoo.com 3 2300.61
barryz#gmail.com 1 303.79
chrisb#gmail.com 1 1678.6
david#hotmail.com 2 788.3
erinv#gmail.com 1 299
frank#gmail.com 3 1539.19
garyz#yahoo.com 1 679.99
Can anyone help me to do this?
As you said in the question, use GROUP BY and aggregate the number of orders and the total:
select c.email_address,
COUNT(o.order_id) as "Number of Orders",
SUM((oi.item_price-oi.discount_amount)*oi.quantity) as "Total amount"
from customers c
inner join orders o on c.customer_id=o.customer_id
inner join order_items oi on o.order_id=oi.order_id
GROUP BY c.email_address
You can wrap your query:
select email_address, count("Number of Orders") as number_of_orders, sum("Total Amount") as amount
from (
select c.email_address,o.order_id as "Number of Orders",
((oi.item_price-oi.discount_amount)*oi.quantity) as "Total amount"
from customers c
inner join orders o on c.customer_id=o.customer_id
inner join order_items oi on o.order_id=oi.order_id
)Z
group by email

SQL Query to get value of recent order alongwith data from other tables

I am writing an SQL query to get data from more than 3 tables, but for simplifying the question here I am using a similar scenario with 3 tables.
Table1 Customer (PK-CustomerID, Name)
CustomerID
Name
1
John
2
Tina
3
Sam
Table2 Sales (FK-Id, SalePrice)
ID
SalePrice
1
200.00
2
300.00
3
400.00
Table3 Order (PK-Id, FK-CustomerID, Date, Amount)
Id
CustomerID
Date
Amount
101
1
25-09-2021
30.0
102
1
27-09-2021
40.0
103
2
19-09-2021
60.0
In the output, Date and Amount should be the from most recent Order (latest Date), for a customer
My approach was
Select c.CustomerID, c.Name, s.SalePrice, RecentOrder.Date, RecentOrder.Amount from
Customer as c
LEFT JOIN Sales s ON c.CustomerID = s.ID
LEFT JOIN (SELECT top 1 o.Date, o.Amount, o.CustomerID
FROM Order o, Customer c1 WHERE c1.CustomerID = o.CustomerID ORDER BY o.Date DESC)
RecentOrder ON c.CustomerID = RecentOrder.CustomerID
Output I get
CustomerID, Name, SalePrice, Date, Amount
CustomerID
Name
SalePrice
Date
Amount
1
John
200.00
27-09-2021
40.0
2
Tina
300.00
null
null
3
Sam
400.00
null
null
The output I get includes the most recent order out of all the orders. But I want to get the recent order out of the orders made by that customer
Output Required
CustomerID, Name, SalePrice, Date, Amount
CustomerID
Name
SalePrice
Date
Amount
1
John
200.00
27-09-2021
40.0
2
Tina
300.00
19-09-2021
60.0
3
Sam
400.00
null
null
Instead of subquery in left join, you can check with outer apply.
Check following way
Select c.CustomerID, c.Name, s.SalePrice, RecentOrder.Date, RecentOrder.Amount
from Customer c
LEFT JOIN Sales s ON c.CustomerID = s.ID
OUTER APPLY (
SELECT top 1 o.Date, o.Amount, o.CustomerID
FROM [Order] o
WHERE o.CustomerID = c.CustomerID ORDER BY o.Date DESC) RecentOrder`
You need to pre-aggregate or identify the most recent order for each customer order, your query is selecting 1 row for all orders.
Try the following (untested!)
select c.CustomerID, c.Name, s.SalePrice, o.Date, o.Amount
from Customer c
left join Sales s on c.CustomerID = s.ID
outer apply (
select top (1) date, amount
from [order] o
where o.CustomerId=c.CustomerId
order by Id desc
)o

Sum between 3 linked tables SQL Server

I am trying to pull a sum from linked table.
Order:
OrderID LocationID OrderDate
100 1 1/1/2000
200 2 1/2/2000
OrderedItems:
ID OrderID ItemID
1 100 1
2 200 2
3 200 2
4 100 3
OrderItem:
ItemID ItemName Cost
1 Mobile1 100.00
2 Mobile2 200.00
3 Mobile3 300.00
The Order table is effectively a group of OrderedItems. Each row in OrderedItems links back to OrderItem via the ItemID.
I am trying to add a column to the below query for order total.
Order Number Location Date Ordered Order Total
-------------------------------------------------------
100 Sydney 1/1/2000 400
200 Brisbane 1/2/2000 400
The current query I have is:
SELECT
Order.OrderID AS [Order Number],
OL.Name AS [Location],
Order.OrderDate AS [Date Ordered]
FROM
Order
LEFT JOIN
Office_Locations AS OL ON OL.id = Order.LocationID
I have tried to follow this link however I am needing to link through 3 tables for the values to add.
Any hep would be great!
You're not finding a sum from three tables. You're finding a sum from one table: the OrderItem table. The only trick is getting the JOIN and GROUP BY expressions done correctly to make that column available.
SELECT o.OrderID As [Order Number], l.Name As Location
, o.OrderDate As [Date Ordered], SUM(i.Cost) As [Order Total]
FROM [Order] o
INNER JOIN Office_Locations l on l.id = o.LocationID
INNER JOIN OrderedItems oi on oi.OrderID = o.OrderID
INNER JOIN OrderItem i ON i.ItemID = oi.ItemID
GROUP BY o.OrderID, l.Name, o.OrderDate
SQLFIDDLE
You need to use SUM to get the total Cost:
SQL Fiddle
SELECT
[Order Number] = o.OrderID,
Location = ol.Name,
[Date Ordered] = o.OrderDate,
[Order Total] = SUM(i.Cost)
FROM [Order] o
INNER JOIN OrderedItems oi
ON oi.OrderId = o.OrderId
INNER JOIN OrderItem i
ON i.ItemID = oi.ItemID
LEFT JOIN Office_Locations ol
ON ol.id = o.LocationID
GROUP BY
o.OrderID, o.OrderDate, ol.Name
As commented by Joel Coehoorn, it's more normal to have a quantity field in the OrderedItems table than to repeat them. Following his advise, your OrderedItems table should be:
ID OrderID ItemID Quantity
1 100 1 1
2 200 2 2
3 100 3 1
Additional Notes:
Use meaningful aliases to improve readability.
Refrain from using reserved words as your object names i.e. Order could be renamed as OrderHeader.

SQL subquery and aggregate function

I am just learning about SQL subqueries, and I am a little confused as to why this isn't working. I have two tables, Order and OrderDetails. They both have an OrderID, and the OrderDetails has the fields OrderDetails.ProductID and OrderDetails.Quantity. So different orders can have different products, and on the OrderDetails table, there can be multiple rows for an OrderID if the Order has more than one different product.
so on the Orders Table it could be like
OrderID
10248
10249
10250
and in the OrderDetails Table:
OrderID | ProductID | Quantity
10248 | 11 | 12
10248 | 42 | 10
10248 | 72 | 5
etc
What I want to do is print out a list of all OrderIDs that have more than 1 product ordered.
I thought the following made sense:
Select Orders.OrderID
FROM Orders
WHERE Orders.OrderID = (Select OrderDetails.OrderID
FROM OrderDetails
GROUP BY OrderDetails.OrderID
HAVING (COUNT(OrderDetails.ProductID) > 1))
But this is certainly not working. Only one order ID is printed even though basically ever OrderID in the database has multiple products. I hope the way I asked this wasn't too confusing, it's my first time posting about SQL on here
This is all you need, your inner query.
Select OrderID
FROM OrderDetails
GROUP BY OrderID
HAVING COUNT(*) > 1
And if you want the other fields from the main Order table for these Orders with multiple products, then use the following.
SELECT *
FROM Orders
WHERE OrderId IN (
SELECT OrderID
FROM OrderDetails
GROUP BY OrderID
HAVING COUNT(*) > 1
)