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
Related
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
I have a dataset with the following columns
city
user
week
month
earnings
Ideally I want to calculate a 50th % from percentile_cont(earnings,0.5) over (partition by city order by month range between 1 preceding and current row). But Big query doesn't support window framing in percentile_cont. Can anyone please help me if there is a work around this problem.
If I understand correctly, you can aggregate into an array and then unnest:
select t.*,
(select percentile_cont(earning) over ()
from unnest(ar_earnings) earning
limit 1
) as median_2months
from (select t.*,
array_agg(earnings) over (partition by city
order by month
range between 1 preceding and current month
) as ar_earnings
from t
) t;
You don't provide sample data, but this version assumes that month is an incrementing integer that represents the month. You may need to adjust the range depending on the type.
SELECT SUM(Total_A ) FROM Materials_List
This is the snippet of code that I have.
I need it to calculate by month and display by month using SQL.
I also would like it to be a code I can use for any month in the year not just one month at a time.
You seem to be looking for simple aggregation:
select
year(materials_datetime) yr,
month(materials_datetime) mn,
sum(total_a) sum_total_a
from materials_list
group by
year(materials_datetime),
month(materials_datetime)
order by yr, mn
This assumes that column materials_datetime contains the date/time that you want to use to aggregate the data.
I have a table with count by product. I am trying to add a new column that would find % as compared to sum of all rows in that column.
prod_name,count
prod_a,100
prod_b,50
prod_c,150
For example, I want to find % of prod_a as compared to the total count and so on.
Expected output:
prod_name,count,%
prod_a,100,0.33
prod_b,50,0.167
prod_c,150,0.5
Edit on SQL:
select count(*),ratio_to_report(prod_name)
over (partition by count(*))
from sales
group by prod_name;
Using window functions.
select t.*,100.0*cnt_by_prod/sum(cnt_by_prod) over() as pct
from tbl t
Edit: Based on OP's question change, To compute the counts and then percentage, use
select prod_name,100.0*count(*)/sum(count(*)) over()
from tbl
group by prod_name
I have a table with two fields
DATE_YYYYMM
TOTAL
That table contains the accumulated total per month for the whole year.
I'd like a query retrieving the "unacumulated" total for each month.
For example, the total of 201806 would be equal to the total of 201806 minus the one of 201805.
Any tip please ? Thanks !
The window function LAG can be used to get a previous value based on an order.
And it seems you just want to subtract the previous month's total from the total.
SELECT
DATE_YYYYMM,
TOTAL,
TOTAL - ISNULL(LAG(TOTAL) OVER (ORDER BY DATE_YYYYMM), 0) AS UNACCUMULATED
FROM YourYearTotalsTable
You can use the analytic function LAG (starting from sql-server-2012) to compare values in the current row with values in a previous row.
SELECT
[date_yyyymm]
,[current_total] = [total]
,[previous_total] = LAG([total], 1, 0) OVER (ORDER BY [date_yyyymm])
,[unacumulated] = [total] - LAG([total], 1, 0) OVER (ORDER BY [date_yyyymm])
FROM [your_table]
ORDER BY [date_yyyymm];