SUM of multi (relate to another table) rows record in another table - sql

I have two tables an tblOrder and tblOrderDetail Table.
tblOrderDetail contain below rows:
OrderDetailID OrderID Product Quantity UnitPrice Discount Total
1 1 ABC 10 $240.00 10 $2,160.00
2 2 CDF 100 $200.00 10 $18,000.00
3 3 GHI 200 $150.00 0 $30,000.00
4 1 XYZ 40 $100.00 5 $3,800.00
i want sql query to get Subtotal column in tblOrder, which are sum of relate OrderID Total from tblOrderDetail like this:
OrderID Sub Total
1 $5,960.00
2 $18,000.00
3 $30,000.00
i try this sql query:
SELECT
OrderID
,(
SELECT
SUM(((tblOrderDetail.UnitPrice) - (tblOrderDetail.UnitPrice * (tblOrderDetail.Discount / 100))) * (tblOrderDetail.Quantity))
FROM
tblOrderDetail
WHERE tblOrderDetail.OrderID = tblOrder.OrderID
) AS [Sub Total]
FROM
tblOrder
but it gives this
OrderID Sub Total
1 $0.00
2 $0.00
3 $0.00
Note i want Sub Total column dynamically not by Sum of Total Column in tblOrderDetail Table.
I hope somebody can make sense of what I'm saying and hopefully help me achieve this!

Use Group by Clause to with SUM aggregate function,
Select *, sum(Total) as totalforOrder from ordertbl group by OrderID;
Demo SQLFiddle
as per your question, here is a correlated query
SELECT
tblOrder.OrderID
,(
SELECT
SUM(((tblOrderDetail.UnitPrice) - (tblOrderDetail.UnitPrice * (tblOrderDetail.Discount / 100))) * (tblOrderDetail.Quantity))
FROM
tblOrderDetail
WHERE tblOrderDetail.OrderID = tblOrder.OrderID
) AS SubTotal
FROM
tblOrder;
Its working fine on SQLFiddle

you can use Group by to do this
Select OrderID, sum(Total) as [Sub Total] from tblOrderDetail group by OrderID;
You can get more details here !

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

Getting total amount of orders using sql query

Hi lets say i have the following tow tables
first table is Orders which consist of following columns
Order_ID OrderDate
1 2016-01-20
2 2016-01-21
and the second table is OrderDetails which consist of following columns
Order_ID ProductID UnitPrice Quantity
1 1 5.00 1
1 3 20.00 3
2 2 10.00 2
How can i get the following out put
Order_ID OrderDate OrderTotalamount
1 2016-01-20 65.00
2 2016-01-21 20.00
Would you mind trying something like this out?
SELECT ORD.Order_ID, ORD.OrderDate, SUM(ORDD.UnitPrice * ORDD.Quanity) AS OrderTotalAmount
FROM Orders ORD
INNER JOIN OrderDetails ORDD
ON ORDD.Order_ID = ORD.Order_ID
GROUP BY ORD.Order_ID, ORD.OrderDate
You can try this
SELECT a.Order_ID, a.OrderDate, SUM(Quantity*UnitPrice) as OrderTotalamout
FROM Orders a JOIN OrderDetains ON (a.Order_ID = OrderDetails.Order_ID)
GROUP BY 1, 2;
I hope it works fine for you.
YOU CAN USE
SELECT TABLE1.Order_ID, TABLE1.OrderDate, SUM(TABLE2.Quantity*TABLE2.UnitPrice) as TotalPrice
FROM TABLE1 JOIN TABLE2 WHERE(TABLE1.Order_ID = TABLE2.Order_ID);

SQL - select top xx% rows

I have a table, sales, which is ordered by descending TotalSales
user_id | TotalSales
----------------------
4 10
2 1.5
5 0.99
3 0.5
1 0.33
What I would like to do is find the percentage of the sum of all sales that the xx% most important sales represent.
For example if I wanted to do it for top 40% sales, here I would get (10+1.5)/(10+1.5+0.99+0.5+0.33)= 86%
But right now I haven't been able to select "top xx% rows".
Edit: DB management system can be MySQL or Vertica or Hive
select Sum(a) as s from sales where a in (Select TotalSales from sales where TotalSales>=x)
GROUP BY a
select Sum(TotalSales) as b from sales group by b
your result is s/b
and x= the percentage you set each time

Multiple counts with different conditions

I want to retrieve and display on one row, the number of sales made by an employee followed by the total number of sales.
SELECT COUNT(SalesID) AS SalesForEmployee, COUNT(SalesID) AS TotalSales
FROM Sales
WHERE EmployeeID = 123
How do I make it so that the where clause only applies to the first column in the select?
SELECT
sum(case when EmployeeID = 123 then 1 else 0 end) AS SalesForEmployee
,COUNT(SalesID) AS TotalSales
FROM Sales
select count(SalesEmp.SalesID) AS SalesForEmployee count(Sales.salesID) As TotalSales
from Sales left outer join Sales as SalesEmp
on Sales.salesID=SalesEmp.SalesID
and SalesEmp.EmployeeID = 123
You can't have a where that only applies to one column.
In order to get both counts while only scanning the table once, you can do this:
select
sum(case when EmployeeID=123 then 1 else 0 end) as SalesForEmployee,
Count(SalesID) as TotalSales
from Sales
There's no where clause because Count(SalesID) needs to count every row to give you the total count.
Since you have to look at every row, case when EmployeeID=123 then 1 else 0 end gives you a 1 for each row that belongs to the target employee and a 0 for every row that doesn't. Therefore, summing that expression gives you the count only for that employee.
SalesID EmployeeID (case when ... )
1 123 1
2 311 0
3 333 0
4 123 1
5 300 0
count = 5 sum = 2
You could also do it like this:
select
(select count(SalesID) from Sales where EmployeeID=123) as SalesForEmployee,
(select count(SalesID) from Sales) as TotalSales
But now you are scanning the Sales table twice, which will be slower.
This is a nested subquery approach combining two select statements into one.
SELECT
(SELECT COUNT(SalesID) FROM Sales WHERE EmployeeID = 123) AS SalesForEmployee,
(SELECT COUNT(SalesID) FROM Sales) AS TotalSales
Another way to write it would be like this.
SELECT COUNT(SalesID) AS SalesForEmployee,
(SELECT COUNT(SalesID) FROM Sales) AS TotalSales
FROM Sales WHERE EmployeeID = 123
With a correlated subquery, you can link the outer query with the inner query. Say you wanted to get the Total sales not including the sales of EmployeeID 123
SELECT COUNT(SalesEmployee.SalesID) AS SalesForEmployee,
(SELECT COUNT(SalesID) FROM Sales WHERE Sales.EmplyeeID <> SalesEmployee.EmployeeID) AS TotalSales
FROM Sales As SalesEmployee WHERE SalesEmployee.EmployeeID = 123
Here the inner query is referencing the outqueries EmployeeeID in the WHERE clause to filter them out.

Get max of column using sum

I have one table with following data..
saleId amount date
-------------------------
1 2000 10/10/2012
2 3000 12/10/2012
3 2000 11/12/2012
2 3000 12/10/2012
1 4000 11/10/2012
4 6000 10/10/2012
From my table I want result with max of sum amount between dates 10/10/2012 and 12/10/2012 which for the data above will be:
saleId amount
---------------
1 6000
2 6000
4 6000
Here 6000 is the max of the sums (by saleId) so I want ids 1, 2 and 4.
You have to use Sub-queries like this:
SELECT saleId , SUM(amount) AS Amount
FROM Table1
GROUP BY saleId
HAVING SUM(amount) =
(
SELECT MAX(AMOUNT) FROM
(
SELECT SUM(amount) AS AMOUNT FROM Table1
WHERE date BETWEEN '10/10/2012' AND '12/10/2012'
GROUP BY saleId
) AS A
)
See this SQLFiddle
This query goes through the table only once and is fairly optimised.
select top(1) with ties saleid, amount
from (
select saleid, sum(amount) amount
from tbl
where date between '20121010' and '20121210'
group by saleid
) x
order by amount desc;
You can produce the SUM with the WHERE clause as a derived table, then SELECT TOP(1) in the query using WITH TIES to show all the ones with the same (MAX) amount.
When presenting dates to SQL Server, try to always use the format YYYYMMDD for robustness.