how can i add
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW on sum column?
because the lead/lag function dont work
used the cod :
select year (orderdate),month (orderdate),sum (SubTotal),
lead ( sum (SubTotal),0) OVER ( PARTITION BY sum (SubTotal) ORDER BY sum (SubTotal) ) as PrevOrder
from sales.SalesOrderHeader
where orderdate <= '2011-12-31'
group by
grouping sets
((year (orderdate),month (orderdate)), () )
and add a name to the row total sum ?
added the expected output the table to extract the data and my query tablemy query
expected
Related
I have table named Sales.OrderValues that contain of 2 column, namely orderyear and val (total sales per day).
This is the record snippet (I cant show all of record because there are 830 rows)
I want to show the result like this
But, my output is different with my expected output.
As you can see, the expected output of prevtotalsales in 2008 is 618085.30. But, my output is 825169.29 (which is 208083.99 + 617085.30).
Below is my query
SELECT
YEAR(D1.orderdate) AS orderyear,
SUM(D1.val) AS curtotalsales,
(
SELECT
SUM(D2.val)
FROM
Sales.OrderValues D2
WHERE
YEAR(D1.orderdate) > YEAR(D2.orderdate)
)
AS prevtotalsales
FROM
Sales.OrderValues D1
GROUP BY
YEAR(D1.orderdate);
How to show the SUM of totalsales at the previous year without adding the next year's totalsales?
Basically, you want an equality condition in the WHERE clause of the subquery. This:
WHERE YEAR(D1.orderdate) > YEAR(D2.orderdate)
Should be:
WHERE YEAR(D1.orderdate) = YEAR(D2.orderdate) + 1
But it is much simpler and more efficient to just use lag():
SELECT
YEAR(orderdate) AS orderyear,
SUM(val) AS curtotalsales,
LAG(SUM(val)) OVER(ORDER BY YEAR(orderdate)) AS prevtotalsales
FROM Sales.OrderValues
GROUP BY YEAR(orderdate)
ORDER BY orderyear
You need to first SUM the values per year, and then use a cumulative SUM:
WITH Totals AS(
SELECT YEAR(OV.orderdate) AS OrderYear
SUM(OV.Val) AS YearSum
FROM Sales.OrderValues OV
GROUP BY YEAR(OV.orderdate))
SELECT OrderYear,
YearSum,
SUM(YearSum) OVER (ORDER BY OrderYear ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS PreviousCumulative
FROM Totals;
SELECT CUST_ID,CONTACTS
Sum("CONTACTS") Over (PARTITION by "CUST_ID" Order By "end_Period" ROWS UNBOUNDED PRECEDING) as RunningContacts,
"SALES",
Sum("SALES") Over (PARTITION by "CUST_ID" Order By "end_Period" ROWS UNBOUNDED PRECEDING) as RunningSales,
end_Period
FROM Table2
I have currently created the Running growth column in excel formula is (New Runningsales - Previous Running sales) / Previous RunningSales.
Any help here is appreciated.
Are you looking for this?
select t.*,
RunningSales / (Running - Sales) - 1
from (< your query here > ) x
The SQL derived table can hold a query to aggregate sales by period, and you an join such to itself to compare each period to the prior period.
with cte
as
(
SELECT
year(h.orderdate)*100+month(h.orderdate) as yearmonth,
YEAR(h.orderdate) as orderyear,
sum(d.OrderQty*d.UnitPrice) as amount
FROM [AdventureWorks].[Sales].[SalesOrderDetail] d
inner join sales.SalesOrderHeader h
on d.SalesOrderID=h.SalesOrderID
group by
year(h.orderdate)*100+month(h.orderdate),
year(h.orderdate)
)
select
c.*,
last_value(c.amount) over (partition by c.orderyear order by c.yearmonth) as lastvalue,
first_value(c.amount) over (partition by c.orderyear order by c.yearmonth) as firstvalue
from cte c
order by c.yearmonth
I am expecting to see the lastvalue of each year (say december value), similar to the firstvalue of each year (jan value). however, last_value is not working at all. It just returns the same value of that month. What did I do wrong?
Thanks for the help.
Your problem is that the default row range for LAST_VALUE is RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, so the value you are getting is the current month's value (that being the last value in that range). To get LAST_VALUE to look at all values in the partition you need to expand the range to include the rows after the current row as well. So you need to change your query to:
last_value(c.amount) over (partition by c.orderyear order by c.yearmonth
rows between unbounded preceding and unbounded following) as lastvalue,
I have a query that is working fine: The query is to find the sum & Avg for the last 3 months and last year. It is working fine, till I got a new request to break the query down to more details by AwardCode.
So how to include that?
I mean for this section
SUM(1.0 * InvolTerm) OVER (ORDER BY Calendar_Date ASC
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS InvolMov3Mth,
I want to find the last 3 months based on AwardCode.
My original query that is working is
SELECT
Calendar_Date, Mth, NoOfEmp, MaleCount, FemaleCount,
SUM(1.0*InvolTerm) OVER (ORDER BY Calendar_Date ASC
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS InvolMov3Mth,
SUM(1.0*TotalTerm) OVER (ORDER BY Calendar_Date ASC
ROWS BETWEEN 11 PRECEDING AND CURRENT ROW) AS TermSum12Mth
FROM #X
The result is
But now I need to add another group AwardCode
SELECT
Mth, AwardCode, NoOfEmp, MaleCount, FemaleCount,
SUM(1.0 * InvolTerm) OVER (ORDER BY Calendar_Date ASC
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS InvolMov3Mth,
SUM(1.0 * TotalTerm) OVER (ORDER BY Calendar_Date ASC
ROWS BETWEEN 11 PRECEDING AND CURRENT ROW) AS TermSum12Mth
FROM #X
The result will be like this
You can notice that the sum of InvolMov3Mth & TermSum12Mth for the whole period does not match the query above
I think I found the answer for my question.
I used PARTITION BY AwardCode before ORDER BY
seems to be working.
SUM(1.0*TotalTerm) OVER (PARTITION BY AwardCode ORDER BY Calendar_Date ASC
ROWS BETWEEN 11 PRECEDING AND CURRENT ROW) AS TermSum12Mth,
Yes. "Partition by" will make it work for your requirment
I am having trouble counting the TotalAmount incrementing by however many more number of policies there are iterating through each row.
For Example consider the following code:
SELECT
Customer.custno,
Customer.enteredDate AS 'Date Entered',
COUNT(BasicPolInfo.polid) AS 'Number of Policies',
SUM( COUNT(BasicPolInfo.polid)) over() AS TotalAmount
FROM Customer
INNER JOIN BasicPolInfo ON Customer.custid = BasicPolInfo.custid
WHERE BasicPolInfo.polid IS NOT NULL
and Customer.firstname IS NOT NULL
AND Customer.enteredDate > '1/1/79'
GROUP BY Customer.custno, Customer.firstname, Customer.lastname, Customer.entereddate
ORDER BY Customer.enteredDate ASC
What I would like to see is the TotalAmount Column be added from the Number of Policies iterating through each and every customer.
ex:
21 -- date -- 6 -- 6
24 -- date -- 13 -- 19
25 -- date -- 23 -- 32
29 -- date -- 16 -- 48
I could care less for the order of the custno, rather I am more concerned if the total policies are even 159703? There are more than 1000 rows in this SQL.
Please help me how I am able to sum each row from the preceding total sum!
In SQL Server 2012 forward you can use ROWS in an analytic/window function to get a running aggregate:
SELECT Customer.custno
, Customer.enteredDate AS 'Date Entered'
, COUNT(BasicPolInfo.polid) AS 'Number of Policies'
, SUM(COUNT(BasicPolInfo.polid)) OVER (ORDER BY Customer.custno ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS TotalAmount
FROM Customer
INNER JOIN BasicPolInfo ON Customer.custid = BasicPolInfo.custid
WHERE BasicPolInfo.polid IS NOT NULL
AND Customer.firstname IS NOT NULL
AND Customer.enteredDate > '1/1/79'
GROUP BY Customer.custno
, Customer.firstname
, Customer.lastname
, Customer.entereddate
ORDER BY Customer.enteredDate ASC
Note that while you don't care about the order, an ORDER BY is required in order to determine which rows precede the current row.
It appears you are looking for a cumulative total.
This can be done via a CTE, joining the table on itself, a subquery or as of 2012 by using the "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" in the aggregate windowed function.
This can be done with any aggregated windowed function. You need to use
OVER (ORDER BY ______ ORDER BY ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
*Note you need to use order by to specify the arrangement of the column.
The below link to another stack overflow question provides some clear examples.
how to get cumulative sum