Group by and calculation from value on the next row - sql

I'm quite new to sql server. I can't seem to figure this out. I have a table that looks like this.
I need to be able to calculate the percentage change in the number for each name, for each year, in the column p. So the end result should look like this.

You can easily calculate the % difference using lag()
select name, date, number,
Cast(((number * 1.0) - Lag(number,1) over(partition by name order by date))/ Lag(number,1) over(partition by name order by date) * 100 as int)
from table

Related

Adding grouping in framing clause window while creating partitions

Using the dataset hosted on Google (MBL Data) as an example, here is what I am accomplishing to do - obtain last 3 weeks score run for a given Venue.
My aggregated dataset looks like this without the strikes_3wk column -
Logic for strikes_3wk column is to partition the aggregated dataset by venueName, order by YearWeek column and then obtain the last 3 weeks aggregated strikes data.
Here is the query I have written so far. I see that the windowing function is where I need to modify the logic. So, is there a way to add grouping within the windowing function? Is there any alternative way of doing this?
In the image I added a new column 'expected', showing values for two weeks.
select inr.*
,sum(inr.strikes) over (Venue_Week rows between current row and 2 following) as strikes_3wk
from
(
select seasonType
,gameStatus
,homeTeamName
,awayTeamName
,venueName
,CAST(
CONCAT(
CAST(EXTRACT(YEAR FROM createdAt) as string)
,CAST(EXTRACT(WEEK(Monday) FROM createdAt) as string)
) as INT64)
as YearWeek
,sum(homeFinalRuns) as homeFinalRuns
,sum(strikes) as strikes
from `bigquery-public-data.baseball.games_wide`
where createdAt is not null
group by seasonType
,gameStatus
,homeTeamName
,awayTeamName
,venueName
,YearWeek
)inr
window Venue_Week as (
partition by inr.venueName
order by inr.YearWeek desc
)
So you are looking for strikes per venue regardless of who did them, right?
May be something like:
SELECT INR.*, STATS.strikes_3wk
FROM `bigquery-public-data.baseball.games_wide` INR
LEFT JOIN (
SELECT venueName, SUM(strikes) as strikes_3wk
FROM `bigquery-public-data.baseball.games_wide` INR2
WHERE YearWeek IN (
SELECT TOP 3 YearWeek
FROM `bigquery-public-data.baseball.games_wide`
WHERE venueName = INR2.venueName
ORDER BY YearWeek DESC
)
GROUP BY venueName
) STATS
ON INR.venueName = STATS.venueName

SQL Server: Create sequence column based on a non-distinct column

I'm not sure if I'm asking this question right, but hopefully I can explain it well enough. I have a table that has a Date, Value, and WeekEndDate column. I want to create a sequence column that counts the distinct weeks from 1-13 and cycles every 13 weeks.
I attached a small sample of the output I'm trying to create. Is this even possible?
Use dense_rank() and some arithmetic:
select t.*,
((dense_rank() over (order by weekEnd) - 1) % 13) + 1
from t;

SQL Aggregation / Window Function for Summarizing Data

I would like to create a query to do the following but I am having trouble:
I have a DB table with the columns:
TestYear (int, e.g. 2014)
Date (date, i.e. set of dates in a given year)
DailyWorstValue
RunningValue
Primary key is TestYear + Date
I would like to get the:
LAST RunningValue ordered by Date (i.e. the final value)
MINIMUM WorstValue (i.e. the worst value)
Per TestYear
This will basically be a one-row summary per TestYear. Is it possible to do this using window functions? Thank you very much in advance for any help that you can give.
Am not sure why you need window function to do this just aggregate function will do the job for you
SELECT testyear,
MIN_DailyWorstValue = Min(dailyworstvalue),
RV.last_runningvalue
FROM db_table A
CROSS apply (SELECT TOP 1 Last_RunningValue= runningvalue
FROM db_table B
WHERE A.testyear = B.testyear
ORDER BY date DESC) RV
GROUP BY testyear,
RV.last_runningvalue

T-SQL average calculation

I want to incorporate two average calculations for a bunch of value columns in my select statement.
see this link for my simplified table structure including the desired output calculation: Pastebin
1) moving average:
Month1 = value of the value1-column for that month, Month2 = if sum == 0 then write 0, else avg(Month1 and Month2) and so on.
So for each product, I want the moving average for each month within one year.
I have this set up in my Excel but I can't transfer the expression to sql.
2) overall average:
for each product, calculate the average over all years and duplicate the calculated value to all rows for that product.
I hope you can help me out with this. It looks like I need a procedure but maybe it is just a simple statement.
SQL-Server 2012 supports the analytic functions required to do this:
SELECT Product,
Month,
Year,
Value,
AVG_YTD = AVG(Value) OVER(PARTITION BY Year ORDER BY Month),
AVG_Year = AVG(Value) OVER(PARTITION BY Product, Year),
AVG_Overall = AVG(Value) OVER(PARTITION BY Product)
FROM T;
Simplified Example on SQL Fiddle

get previous from max value

I have folowing sql query an di want to get previous of max value from table.
select max(card_no),vehicle_number
FROM WBG.WBG_01_01
group by vehicle_number
Through this query i got each maximum card number of each vehicle.But i want to get previouse of that max.For example
if vehicle number has card number 21,19,17,10,5,6,1 and i want to get 19 from max function
Please anyone tell me how can i do this in sql.
Another idea would be to use analytics, something like this:
select
vehicle_number,
prev_card_no
from (
select
card_no,
vehicle_number,
lag(card_no) over
(partition by vehicle_number order by card_no) as prev_card_no,
max(card_no) over
(partition by vehicle_number) as max_card_no
FROM WBG.WBG_01_01
)
where max_card_no = card_no;
Of course, this doesn't take into account your seemingly arbitrary ordering from your question, nor would it work with duplicate maximum numbers.
try this one:
select max(card_no),vehicle_number
FROM WBG.WBG_01_01
where card_no < (Select max(card_no) from WBG.WBG_01_01 group by vehicle_number)
group by vehicle_number