How to sum() prices between date ranges? - sql-server

I'm trying to figure out how to make an operation in my table to get a sum of prices by periods; basically i have 4 tables: 'Rooms','Medias','Details' and 'Prices';
Room is my main table with IDs, and i need to join child tables to get details, media and prices for each unit. That works fine as now:
#From as date
#To as date
SELECT
Unit.Id,
Unit.Description,
Details.Description,
Medias.path,
FROM Unit
LEFT JOIN Details
ON Unit.Id = Details.UnitId
LEFT JOIN Medias
ON Unit.Id = Medias.UnitId
I now need to add a third join to 'Price' table who has a structure like this:
Id UnitId From To Price
-----------------------------------------------
1 1855 2022-06-18 2022-07-08 203.8600
2 1855 2022-07-09 2022-08-12 128.5700
3 1855 2022-08-13 2022-08-19 102.8600
4 2600 2022-06-18 2022-07-08 231.8600
5 2600 2022-07-09 2022-08-12 322.5700
6 2600 2022-08-13 2022-08-19 122.8600
What i'm trying to do is to add to my select a sum() of Prices over the period that comes to my stored procedure from the variables #From and #To, to get out a total price for a period passed.
For example passing #From = '2022-07-07' and #To = '2022-07-11' it is supposed to give me:
664.86 (203.8600 + 203.8600 + 128.5700 + 128.5700) for the unit 1855
and
1108.86 (231.8600 + 231.8600 + 322.5700 + 322.5700) for the unit 2600
Hope i made this clear, thank you for helping!

Since you only require the Price you could use a correlated subquery, something like:
select u.Id, u.Description, d.Description, m.Path, (
select Sum(Price)
from Prices p
where p.UnitId = u.Id and p.from >= #From and p.to <= #To
) as Price
from Unit u
left join Details d on d.UnitId = u.Id
left join Medias m on m.UnitId = u.Id;

Related

SQL NESTED JOIN ISSUES

I'm having a heck of a time getting my query to work properly. I have 3 tables (ORDERS, ORDERSITEMS, ORDERPAYMENTS) that I'm trying to build a report for monthly sales taxes due which will look like this:
MONTH YEAR TOTAL RECEIPTS EXEMPT RECEIPTS NON-EXEMPT RECEIPTS SALES TAX
1 2020 $5,000 $4,500 $500 $31.25
TOTAL RECEIPTS: To get this number you have to add together all of the C.OrderPayments_Amount for the given time frame, in this case MONTH(C.OrderPayments_Date) = 1 AND YEAR(C.OrderPayments_Date) = 2020
EXEMPT RECEIPTS: You have to determine if an item is taxable (eg. digital files are not sales taxable, physical prints are). To get this you have determine if the item is taxable by checking the B.OrdersItems_ItemChargeSalesTax. If this field is 0 it does not get charged sales tax and if it is 1 then it does. You then have to filter to only get ORDERSITEMS for the Jan 2020 time frame using by grouping by the C.OrderPayments_Date column that have the B.OrdersItems_ItemChargeSalesTax = 0 and finally add the B.OrdersItems_Total together.
NON-EXEMPT RECEIPTS: To get this number you do the same exact thing for EXEMPT RECEIPTS above except you look for B.OrdersItems_ItemChargeSalesTax = 1 and add the B.OrdersItems_Total together.
SALES TAX: To get this number you use the same date filter as before MONTH(C.OrderPayments_Date) = 1 AND YEAR(C.OrderPayments_Date) = 2020 and then add the A.Order_SalesTax column together.
The first query I have listed is working fine to bring me the total taxes paid and the total income for the month (right now I have hard coded the WHERE statement but that is going to be applied via filters on my list page). What I
need to get from the ORDERSITEMS table is a field called ORDERSITEMS_ItemTotal and sum that field so it is a single line entry on the query. I have seen another person do a nested join. Any suggestions would be greatly appreciated.
**ORDERS TABLE "A"**
Order_ID,
Order_SalesTax,
stateTaxAbbreviation
**ORDERSITEMS TABLE "B"**
Order_FK,
OrdersItems_ItemChargeSalesTax,
OrdersItems_Total
NOTE: In the ORDERSITEMS table a single Order_FK may appear several times as there can be many items on an order
**ORDERPAYMENTS TABLE "C"**
Order_FK,
OrderPayments_PaymentDate,
OrderPayments_Amount
NOTE: In the ORDERPAYMENTS table a single Order_FK may appear several times as there can be multiple payments on an order
While writing this out it seems to be an easy task but when I attempt to put it all together the numbers are wrong because it is adding entries multiple times because there are multiple items on an order and thus it is adding the total payment every time.
Here is the code that I've been tinkering with and I would really appreciate any guidance. Thank you in advance and hopefully I've explained my situation clearly enough.
Select
a.stateTaxAbbreviation AS StateAbbr,
MONTH(c.OrderPayments_Date) AS PaymentMonth,
YEAR(c.OrderPayments_Date) AS PaymentYear,
SUM(c.OrderPayments_Amount) AS TotalPayments,
SUM(a.Order_SalesTax) AS sales_tax
FROM dbo.ORDERS a
INNER JOIN ORDERPAYMENTS as c ON c.Order_FK = a.Order_ID
LEFT OUTER JOIN ORDERITEMS b on b.Order_FK = a.Order_ID
WHERE a.stateTaxAbbreviation = 'MA' AND Month(b.OrderPayments_Date) = 1 AND YEAR(b.OrderPayments_Date) = 2020
GROUP BY stateTaxAbbreviation , MONTH(c.OrderPayments_Date), Year(c.OrderPayments_Date)
You should probably write 2 queries, one where you join the ORDERPAYMENTS table, and another where you join the ORDERITEMS table. Then you can combine them with UNION ALL.
Something like this:
SELECT StateAbbr,PaymentMonth,PaymentYear,SUM(TotalPayments),SUM(sales_tax),SUM(OrdersItems_Total)
FROM (
Select
a.stateTaxAbbreviation AS StateAbbr,
MONTH(c.OrderPayments_Date) AS PaymentMonth,
YEAR(c.OrderPayments_Date) AS PaymentYear,
SUM(c.OrderPayments_Amount) AS TotalPayments,
SUM(a.Order_SalesTax) AS sales_tax,
0 as OrdersItems_Total
FROM dbo.ORDERS a
INNER JOIN ORDERPAYMENTS as c ON c.Order_FK = a.Order_ID
WHERE a.stateTaxAbbreviation = 'MA' AND Month(c.OrderPayments_Date) = 1 AND YEAR(c.OrderPayments_Date) = 2020
GROUP BY stateTaxAbbreviation , MONTH(c.OrderPayments_Date), Year(c.OrderPayments_Date)
UNION ALL
Select
a.stateTaxAbbreviation AS StateAbbr,
MONTH(c.OrderPayments_Date) AS PaymentMonth,
YEAR(c.OrderPayments_Date) AS PaymentYear,
0 AS TotalPayments,
0 AS sales_tax,
SUM(B.OrdersItems_Total) as OrdersItems_Total
FROM dbo.ORDERS a
INNER JOIN ORDERITEMS b on b.Order_FK = a.Order_ID
WHERE a.stateTaxAbbreviation = 'MA' AND Month(b.OrderPayments_Date) = 1 AND YEAR(b.OrderPayments_Date) = 2020
GROUP BY stateTaxAbbreviation , MONTH(c.OrderPayments_Date), Year(c.OrderPayments_Date)
)t
GROUP BY StateAbbr,PaymentMonth,PaymentYear
Thanks to Wouter for pointing me in the right direction. After looking at his suggestion I went back and evaluated what I needed and I create the solution that worked that was based on his idea. Thanks for your patience Wouter, your insight helped a lot!
Select StateAbbr, OrderYear, OrderMonth, SUM(TotalSales) As TotalSales, SUM(TotalSales)-SUM(TaxableRevenue) As ExemptRevenue, SUM(TaxableRevenue) As TaxableRevenue, SUM(SalesTax) As SalesTax
FROM (
Select
/*Get Total Sales and Total Sales Tax Collected*/
a.stateTaxAbbreviation AS StateAbbr,
MONTH(a.Order_Date) As OrderMonth,
YEAR(a.Order_Date) As OrderYear,
SUM((a.Order_TotalBaseSale + a.Order_Shipping) - (((a.Order_PercentDiscount*a.Order_TotalBaseSale)/100) + a.Order_DollarDiscount)) As TotalSales,
SUM(0) As ExemptRevenue,
Sum(0) As TaxableRevenue,
SUM(a.Order_SalesTax) AS SalesTax
FROM dbo.ORDERS a
WHERE a.Order_Status != 'Cancelled'
Group By a.stateTaxAbbreviation, MONTH(a.Order_Date), YEAR(a.Order_Date)
UNION ALL
Select
/*GET EXEMPT ORDERS*/
a.stateTaxAbbreviation AS StateAbbr,
MONTH(a.Order_Date) As OrderMonth,
YEAR(a.Order_Date) As OrderYear,
Sum(0) As TotalSales,
Sum(OrdersItems_ItemTotal) AS ExemptRevenue,
Sum(0) AS TaxableRevenue,
Sum(0) As SalesTax
FROM ORDERSITEMS b
LEFT JOIN ORDERS a ON Order_ID = b.Order_FK
WHERE b.OrdersItems_ItemChargeSalesTax = 0 and a.Order_Status != 'Cancelled'
Group By a.stateTaxAbbreviation, MONTH(a.Order_Date), YEAR(a.Order_Date)
UNION ALL
Select
/*GET NON-EXEMPT ORDERS*/
a.stateTaxAbbreviation AS StateAbbr,
MONTH(a.Order_Date) As OrderMonth,
YEAR(a.Order_Date) As OrderYear,
SUM(0) As TotalSales,
SUM(0) AS ExemptRevenue,
Sum(OrdersItems_ItemTotal) AS TaxableRevenue,
Sum(0) As SalesTax
FROM ORDERSITEMS b
LEFT JOIN ORDERS a ON Order_ID = b.Order_FK
WHERE b.OrdersItems_ItemChargeSalesTax <> 0 and a.Order_Status != 'Cancelled'
Group By a.stateTaxAbbreviation, MONTH(a.Order_Date), YEAR(a.Order_Date)
)t
GROUP BY StateAbbr, OrderMonth, OrderYear
ORDER BY StateAbbr ASC, OrderYear DESC, OrderMonth ASC

ISNULL() for calculated column in Full Join. SQL Server

I'm currently facing a problem when calculating the standard deviation in an SQL Server statement.
My problem: I have two tables.
T1:
Reg_Month
---------
1
2
3
...
T2:
Product Month Consumption
-------------------------------
ProdA 1 200
ProdB 1 10
ProdA 1 300
ProdC 2 100
ProdA 2 200
...
Now what I want is something like this, for calculating my STDEV over a year:
Reg_Month Product Month Sum
---------------------------------
1 ProdA 1 500
1 ProdB 1 10
1 ProdC 1 0
2 ProdA 2 200
2 ProdB 2 0
2 ProdC 2 0
So now I don't need this table to be set up, but I need to calculate the STDEV and AVG of the column "Sum" for each Product. The Problem is to include the NULLS.
This gives me the table I want for ProdA, but with NULLS whenever there was no consumption:
SELECT *
FROM T1
FULL JOIN (SELECT Product, Month, SUM(Consumption) AS Sum,
FROM T2
WHERE (Product = 'ProdA')
GROUP BY Month, Product) sub ON (T1.Reg_Month = T2.Month)`
This gives me the STDEV:
SELECT Stdev(Sum)
FROM
(SELECT *
FROM T1
FULL JOIN (SELECT Product, Month, SUM(Consumption) AS Sum,
FROM T2
WHERE (Product = 'ProdA')
GROUP BY Month, Product) sub ON (T1.Reg_Month = T2.Month)) sub
WHERE Product = 'ProdA'`
But the problem is, that it doesn't give me the correct STDEV for the entire year, if there is a month in which there was no consumption, because the NULLs (that appear due to the join) are ignored.
My approaches:
ISNULL():
SELECT Stdev(Sum)
FROM
(SELECT *
FROM T1
FULL JOIN (SELECT Product, Month, ISNULL(SUM(Consumption), 0) AS Sum,
FROM T2
WHERE (Product = 'ProdA')
GROUP BY Month, Product) sub ON (T1.Reg_Month = T2.Month)) sub
WHERE Product = 'ProdA'`
doesn't work (maybe because the null is generated after the join?)
CASE:
SELECT Stdev(Sum)
FROM
(SELECT *
FROM T1
FULL JOIN (SELECT Product, Month, CASE WHEN SUM(Consumption) IS NULL THEN 0 ELSE Sum(Consumption) END AS Sum,
FROM T2
WHERE (Product = 'ProdA')
GROUP BY Month, Product) sub ON (T1.Reg_Month = T2.Month)) sub
WHERE Product = 'ProdA'
doesn't work (probably the same reason)
I hope I was able to illustrate my example properly. Now, do you have any idea how get the right results for the STDEV?
Your input would be greatly appreciated!
Thanks a lot,
Clemens
if you are only doing one product at a time
SELECT sum(isnull(T2month.MonthSum ,0))
, Stdev(isnull(T2month.MonthSum ,0))
FROM T1
LEFT JOIN
(select Month, sum(Consumption) as MonthSum
from T2
where Product = 'ProdA'
group by Month) T2month
ON T1.Reg_Month = T2month.Month
for all products
SELECT Product.Name
, sum(isnull(T2month.MonthSum ,0))
, Stdev(isnull(T2month.MonthSum ,0))
FROM T1
cross apply
(values ('ProdA'), ('ProdB'), ('ProdC')) Product(Name)
LEFT JOIN
(select Product, Month, sum(Consumption) as MonthSum
from T2
group by Product, Month) T2month
ON T1.Reg_Month = T2month.Month
AND T2month.Product = Product.Name
Group By Product.Name
Hey OP left join does NOT leave out periods
That is what a left join does
select lj.val, isnull(jj.val,0)
from ( values (1), (2), (3), (4) ) lj(val)
left join ( values (1), (2), (4) ) jj(val)
on lj.val = jj.val
order by lj.val

Counting duplicate items in different order

Goal:
To know if we have purchased duplicate StockCodes or Stock Description more than once on difference purchase orders
So, if we purchase Part ABC on Purchase Order 1 and Purchase Order 2, it should return the result of
PurchaseOrders, Part#, Qty
Purchase Order1, Purchase Order2, ABC, 2
I just don't know how to pull the whole code together, more to the point, how do I know if it's occurred on more than 1 Purchase Order without scrolling through all the results , may also have to do with Multiple (Having Count) Statements as I only seem to be doing by StockCode
SELECT t1.PurchaseOrder,
t1.MStockCode,
Count(t1.MStockCode) AS SCCount,
t1.MStockDes,
Count(t1.MStockDes) AS DescCount
FROM PorMasterDetail t1
INNER JOIN PorMasterHdr t2
ON t1.PurchaseOrder = t2.PurchaseOrder
WHERE Year(t2.OrderEntryDate) = Year(Getdate())
AND Month(t2.OrderEntryDate) = Month(Getdate())
GROUP BY t1.PurchaseOrder,
t1.MStockCode,
t1.MStockDes
HAVING Count(t1.MStockCode) > 1
Using responses I came up with the following
select * from
(
SELECT COUNT(dbo.InvMaster.StockCode) AS Count, dbo.InvMaster.StockCode AS StockCodes,
dbo.PorMasterDetail.PurchaseOrder, dbo.PorMasterHdr.OrderEntryDate
FROM dbo.InvMaster INNER JOIN dbo.PorMasterDetail ON
dbo.InvMaster.StockCode = dbo.PorMasterDetail.MStockCode
INNER JOIN dbo.PorMasterHdr ON dbo.PorMasterDetail.PurchaseOrder = dbo.PorMasterHdr.PurchaseOrder
WHERE YEAR(dbo.PorMasterHdr.OrderEntryDate) = YEAR(GETDATE())
GROUP BY dbo.InvMaster.StockCode, dbo.InvMaster.StockCode,
dbo.PorMasterDetail.PurchaseOrder, dbo.PorMasterHdr.OrderEntryDate
) Count
Where Count.Count > 1
This returns the below , which is starting to be a bit more helpful
In result line 2,3,4 we can see the same stock code (*30044) ordered 3 times on different
purchase orders.
I guess the question is, is it possible to look at If something was ordered more than once within say a 30 day period.
Is this possible?
Count StockCodes PurchaseOrder OrderEntryDate
2 *12.0301.0021 322959 2014-09-08
2 *30044 320559 2014-01-21
8 *30044 321216 2014-03-26
4 *30044 321648 2014-05-08
5 *32317 321216 2014-03-26
4 *4F-130049/TEST 323353 2014-10-22
5 *650-1157/E 322112 2014-06-24
2 *650-1757 321226 2014-03-27
SELECT *
FROM
(
SELECT h.OrderEntryDate, d.*,
COUNT(*) OVER (PARTITION BY d.MStockCode) DupeCount
FROM
PorMasterHdr h
INNER JOIN PorMasterDetail d ON
d.PurchaseOrder = h.PurchaseOrder
WHERE
-- first day of current month
-- http://blog.sqlauthority.com/2007/05/13/sql-server-query-to-find-first-and-last-day-of-current-month/
h.OrderEntryDate >= CONVERT(VARCHAR(25), DATEADD(dd,-(DAY(GETDATE())-1),GETDATE()),101)
) dupes
WHERE
dupes.DupeCount > 1;
This should work if you're only deduping on stock code. I was a little unclear if you wanted to dedupe on both stock code and stock desc, or either stock code or stock desc.
Also I was unclear on your return columns because it almost looks like you're wanting to pivot the columns so that both purchase order numbers appear on the same line.

Count Function with Linked Table

I am attempting to count the number of parts ordered by each of our customers in 2013. However the returned results seem to be grouped by order number and not trader. I am using the following select statement;
SELECT orders.traderid, COUNT(orderitems.partid) AS configuredparts
FROM orders LEFT JOIN orderitems
ON orders.id = orderitems.orderid AND orders.ordertype = orderitems.ordertype
WHERE (orderitems.partid LIKE N'P%') AND (YEAR(orders.createddate) = 2013)
GROUP BY orders.traderid, orderitems.partid, orders.ordertype
HAVING (orders.ordertype = N'SO')
ORDER BY orders.traderid
an example of my results are
traderid configured parts
800001 3
800001 3
800001 2
800001 1
A00002 1
A00002 2
Any help is much appreciated
This answer gives the total number (count) of part ids in table [order items] by trader id in table [orders].
trader_id part_id total_parts
800001 P001 3
800001 P002 2
A00002 P001 1
If table [order items] has a qty column, you should change COUNT(oi.partid) to SUM(oi.qty).
SELECT
o.traderid as trader_id,
oi.partid as part_id,
COUNT(oi.partid) AS total_parts
FROM
orders as o
LEFT JOIN
orderitems as oi
ON
o.id = oi.orderid AND
o.ordertype = oi.ordertype
WHERE
(oi.partid LIKE N'P%') AND
(o.createddate >= '20130101') AND
(o.createddate < '20140101') AND
(o.ordertype = N'SO')
GROUP BY
o.traderid, oi.partid
ORDER BY
o.traderid, oi.partid
Last but not least, why does the caption have a linked table (server)?
If you are using a linked server you will need to use 4 part notation.
Linked_Server_Name.Database_Name.Schema_Name.Object_Name
give this a go
SELECT orders.traderid, COUNT(orderitems.partid) AS configuredparts
FROM orders LEFT JOIN orderitems AND orders.ordertype = orderitems.ordertype
ON orders.id = orderitems.orderid
WHERE (orderitems.partid LIKE N'P%') AND (orders.createddate >= '20130101')
AND (orders.createddate < '20140101') AND (orders.ordertype = N'SO')
GROUP BY orders.traderid
ORDER BY orders.traderid

how to group in two tables in SQl server?

I have the following issue :
table # 1 structure :
Requests table for example have 2 columns :
Request_ID Branch_Name
1 xx
2 yy
3 xx
4 xx
5 yy
The second table : Requests_Items for example have the following columns
Request_ID Price
1 100
1 30
1 450
2 10
2 18
So i want my result set to be like :
Branch Name Num_of_Requests Total_Price
xx 3 580
Can you please help
select r.Branch_Name,
count(r.request_id) as Num_of_Requests,
sum(i.price) as Total_Price
from Requests r
left join Requests_Items i on i.Request_ID = r.Request_ID
group by r.Branch_Name
jurgen d was almost there
select r.Request_Id, r.Branch_Name,
COUNT(i.Price) as [Number of Requests],
SUM(i.Price) as [Total]
from Requests r
left join Requests_Items i
on r.Request_Id = i.Request_Id
group by r.Request_Id, r.Branch_Name
select r.Branch_Name, COUNT(ri.Request_ID) as Num_of_Requests, SUM(ri.Price) as Total_Price
from dbo.Requests r
left join dbo.Requests_Items ri
on r.Request_ID = ri.Request_ID
group by r.Branch_Name
Let this is my [Employees] Table
Here is my Dept table
I want the output like this using join and group by
So here is the Query for this-
select max(e.salary) as maxsalary,d.Dept from Employees e inner join DEpt d on e.DeptId=d.id group by e.DeptId,d.Dept
enter code here

Resources