I have a Date dimenstion with levels: Year, Month, Day. I am need to get average by month for range like this [Date].[2011].[1].[10]:[Date].[2011].[10].[20]
Something along these lines:
AVG(
EXISTS(
[Date].[Month].MEMBERS
,[Date].[2011].[1].[10]:[Date].[2011].[10].[20]
)
)
Or if you want the daily average:
AVG(
[Date].[2011].[1].[10]:[Date].[2011].[10].[20]
)
Or is you want the average by the count of number of days for the range you specified:
DIVIDE(
SUM([Date].[2011].[1].[10]:[Date].[2011].[10].[20])
,EXISTS(
[Date].[Month].MEMBERS
,[Date].[2011].[1].[10]:[Date].[2011].[10].[20]
).count
)
Related
I'm trying to get the average repairs in the weekdays and weekends within the last 30 days. Each day is tagged whether it's a weekday or a weekend. Holidays are tagged as weekends.
If I use:
AVG(Completed_Repairs) OVER(PARTITION BY day_type ORDER BY UNIX_DATE(WORK_DT) RANGE BETWEEN 30 PRECEDING AND CURRENT ROW)
I only get either the average repairs for all weekdays or for all weekends in the last 30 days depending on what type of day the date is. But I also need the average for the opposite to compute a prorated monthly number. I basically would need another column with the value of the opposite day type.
If I understood correctly, not partitioning might be the way:
with
input as (
select cast('2022-10-11' as date) as WORK_DT, "weekday" as day_type, 307 as completed_repairs union all
select cast('2022-10-12' as date) as WORK_DT, "weekday" as day_type, 100 as completed_repairs union all
select cast('2022-10-09' as date) as WORK_DT, "weekend" as day_type, 750 as completed_repairs union all
select cast('2022-10-10' as date) as WORK_DT, "weekend" as day_type, 647 as completed_repairs
)
select
*,
avg(if(day_type = 'weekday', completed_repairs,0)) OVER(ORDER BY UNIX_DATE(WORK_DT) RANGE BETWEEN 30 PRECEDING AND CURRENT ROW) as avg_weekday,
avg(if(day_type = 'weekend', completed_repairs,0)) OVER(ORDER BY UNIX_DATE(WORK_DT) RANGE BETWEEN 30 PRECEDING AND CURRENT ROW) as avg_weekend,
from input
order by work_dt
You can replace the 0 by null if you don't want the weekends to impact the average of the weekdays and vice-versa.
If you'd rather have a column "matching" and a column "opposite" you can then use the result of this to write a condition depending on the day_type and the column name.
I'd like to find the average monthly revenue for each sales owner--however my current query is taking the monthly total and just dividing it by the number of entries. Ultimately, I'd like to get the average by finding the total revenue for each month and then dividing it by the number of months and then eventually just finding the avg. of the past 6 months. Code as well as sample output below:
select activitydate, console_org_name, partneragency, partneradvertiser, org_sales_owner
,round(sum(gross_revenue_allocation)::numeric,2) as gross_revenue
,round(avg(sum(gross_revenue_allocation)) over (partition by org_sales_owner order by activitydate RANGE INTERVAL '5' MONTH PRECEDING)::numeric,2) as salesowner6monthavg
from data_provider_payout dpp
where activitydate >= '01/01/2019'
group by activitydate, console_org_name, partneragency, partneradvertiser, org_sales_owner
If I understand correctly, you need to aggregate by the month and the owner. That would be something like this:
select date_trunc('month', activitydate), org_sales_owner,
round(sum(gross_revenue_allocation)::numeric, 2) as gross_revenue,
round(avg(sum(gross_revenue_allocation)) over (
partition by org_sales_owner
order by min(activitydate)
range between interval '5 month' preceding and current_row
)
)::numeric, 2) as salesowner6monthavg
from data_provider_payout dpp
where activitydate >= '2019-01-01'
group by date_trunc('month', activitydate), org_sales_owner
I have a table that has entry date and completion date on it (records go back a couple years) and i need to write a query that gives the average amount of time completion takes by each month. I can get the overall average,
SELECT AVG ( t.completion_dt - t.entry_dt ) * 24
FROM table t;
or the average for a specific month,
SELECT AVG ( t.completion_dt - t.entry_dt ) * 24
FROM table t
WHERE t.entry_dt BETWEEN to_date('2018/12/01','yyyy/mm/dd') AND
to_date('2019/1/01', 'yyyy/mm/dd');
Is there a way to get the query to return the average for each month?
If you are wanting to see each month/year independently (Jan 2020 on a different row from Jan 2019), then you can group on your entry_dt field truncated at the month.
SELECT trunc(t.entry_dt,'MM'),
AVG ( t.completion_dt - t.entry_dt ) * 24
FROM table t
group by trunc(t.entry_dt,'MM');
If you are wanting to average ALL January months together across multiple years, you will want to group on something like the to_char of your entry_dt field.
SELECT to_char(t.entry_dt, 'Month'),
AVG ( t.completion_dt - t.entry_dt ) * 24
FROM table t
group by to_char(t.entry_dt, 'Month');
I'm curious as to find the daily average sales for the month of December 1998 not greater than 100 as a where clause. So what I imagine is that since the table consists of the date of sales (sth like 1 december 1998, consisting of different date, months and year), amount due....First I'm going to define a particular month.
DEFINE a = TO_DATE('1-Dec-1998', 'DD-Month-YYYY')
SELECT SUBSTR(Sales_Date, 4,6), (SUM(Amount_Due)/EXTRACT(DAY FROM LAST_DAY(Sales_Date))
FROM ......
WHERE SUM(AMOUNT_DUE)/EXTRACT(DAY FROM LAST_DAY(&a)) < 100
I'm stuck as to extract the sum of amount due in the month of december 1998 for the where clause....
How can I achieve the objective?
To me, it looks like this:
select to_char(sales_date, 'mm.yyyy') month,
avg(amount_due) avg_value
from your_table
where sales_date >= trunc(date '1998-12-01', 'mm')
and sales_date < add_months(trunc(date '1998-12-01', 'mm'), 1)
group by to_char(sales_date, 'mm.yyyy')
having avg(amount_due) < 100;
WHERE clause can be simplified; it shows how to fetch certain period:
trunc to mm returns first day in that month
add_months to the above value (first day in that month) will return first day of the next month
the bottom line: give me all rows whose sales_date is >= first day of this month and < first day of the next month; basically, the whole this month
Finally, the where clause you used should actually be the having clause.
As long as the amount_due column only contains numbers, you can use the sum function.
Below SQL query should be able to satisfy your requirement.
Select SUM(Amount_Due) from table Sales where Sales_Date between '1-12-1998' and '31-12-1998'
OR
Select SUM(Amount_Due) from table Sales where Sales_Date like '%-12-1998'
I am very new to PostgreSQL and to this website. I need your help with this, please.
I need to get all months with more than average rain amount.
I tried this but its not working, may anyone explain?
Select month, rain from weather
where rain > avg(rain)
group by month , rain;
Thanks a lot.
Try this
SELECT month FROM (SELECT month, avg(rain) avg_rain FROM weather GROUP BY month) a
CROSS JOIN
(SELECT avg(rain) rain FROM weather) b
WHERE avg_rain > rain
WITH rain_avg_by_month AS (
SELECT month, AVG(rain) AS rain_avg
FROM weather
GROUP BY month
), total_rain_avg AS (
SELECT AVG(rain_avg)
FROM rain_avg_by_month
)
SELECT month
FROM rain_avg_by_month, total_rain_avg
WHERE rain_avg_by_month.rain_avg > total_rain_avg.avg
;
select * from (
select
month,
rain,
avg(rain) over() avg_rain
from weather
) t
where rain > avg_rain;
Here we assume there is one record per month. First query (the nested one) gives us all months and corresponding rain values along with average rain value (we use window function avg over all records in set). Then the outer query gives us what we need: months where rain value is greater than average rain value.