您好我正在使用的数据主要取决于一周中的哪一天。数据在表格中格式化 日期 - 位置 - 计数/数量。 有多个不同的立场。 我能够使用。
对每周的每一天的数据进行排序select MOD(to_char(time, 'J'),7),
sum(COUNT))
from TABLE
where time > sysdate -x
group by to_char(time, 'J')
order by to_char(time, 'J');
根据星期几输出每日总和。
现在我能够获得一年中一周中一天的平均值。 此代码仅输出星期日的平均值
SELECT AVG(asset_sums)
FROM (
select MOD(to_char(time, 'J'),7),
sum(COUNT)) as asset_sums
from table
where time > sysdate -365
and MOD(TO_CHAR(time, 'J'), 7) + 1 IN (7)
group by to_char(time, 'J')
order by to_char(time, 'J')
);
我的目标是能够获得每日总和与一周中特定日期的年平均值相比较的表格。 例如,星期一的年平均数为57,星期二为60。 本周我的星期一是59,星期二是57.表的输出是 星期一+2,星期二-3。 什么是最简单的方法/最有效的方法? 谢谢你的帮助。
编辑:我的数据格式
日期:yyyy-mm-dd |地点:xxxx | (客户数量)0到10000
2013-09-16 | AAAA | 1534 2013-09-16 | AAAB | 534 2013-09-17 | AAAA | 1434 2013-09-17 | AAAC | 834 2013-09-18 | AAAA | 134 2013-09-18 | AAAD | 183
需要的输出
2013-09-16 |星期几|总和|今年平均周一|差异Sum-AVG
2013-09-16 | 1(=星期一)| 2068年| 2015年| 53
答案 0 :(得分:0)
为清楚起见,我将使用subquery factoring。首先,选择当前的周数据。接下来,子查询当前一周的总和。然后,查询过去一年中每天的总和。然后,平均每周每天的每日总和。最后,加入两个并显示差异。
with
this_week as (
select
time
from table
where time > x - 7
group by time
),
this_week_dly_sum as (
select
to_char(time, 'd') day,
sum(count) sum
from this_week
group by to_char(time, 'd')
),
this_year_dly_sum as (
select
time,
sum(count) sum
from table
where time > x - 365
group by time
),
this_year_dly_avg as (
select
to_char(day, 'd'),
avg(sum) avg
from this_year_dly_sum
group by to_char(day, 'd')
)
select
this_week.time,
to_char(this_week.time, 'day') day of week,
this_week_dly_sum.sum,
this_year_dly_avg.avg,
this_week_dly_sum.sum - this_year_dly_avg.avg difference
from this_week
inner join this_week_dly_sum
on to_char(this_week.time, 'd') = this_week_dly_sum.day
inner join this_year_dly_avg
on to_char(this_week.time, 'd').day = this_year_dly_avg.
group by time
;
答案 1 :(得分:0)
您可以使用分析功能。
select date1, to_char(date1, 'd'),
sum(val) over(partition by to_char(date1, 'd')),
avg(val) over(partition by to_char(date1, 'd')),
sum(val) over(partition by to_char(date1, 'd'))-
avg(val) over(partition by to_char(date1, 'd'))
from table1
time > add_month(sysdate,-12);
答案 2 :(得分:0)
这将为您提供去年的每日计数:
SELECT TRUNC(time, 'DD') AS date,
SUM(count) AS asset_sum
FROM yourtable
WHERE time > SYSDATE - 365
GROUP BY TRUNC(time, 'DD')
您可以修改它以额外返回指定范围的每周每日平均值:
SELECT TRUNC(time, 'DD') AS date,
SUM(count) AS asset_sum,
AVG(SUM(count)) OVER
(PARTITION BY TO_CHAR(TRUNC(time, 'DD'), 'D')) AS asset_sum_avg
FROM yourtable
WHERE time > SYSDATE - 365
GROUP BY TRUNC(time, 'DD')
此时您拥有所需的所有初始数据,但可能需要更多天数。您可以将上述查询用作派生表,将行限制为date > SYSDATE - x
:
WITH last_year_by_day AS
(
SELECT TRUNC(time, 'DD') AS date,
SUM(count) AS asset_sum,
AVG(SUM(count)) OVER
(PARTITION BY TO_CHAR(TRUNC(time, 'DD'), 'D')) AS asset_sum_avg
FROM yourtable
WHERE time > SYSDATE - 365
GROUP BY TRUNC(time, 'DD')
)
SELECT date,
TO_CHAR(TRUNC(time, 'DD'), 'D') AS day_of_week,
asset_sum,
asset_sum_avg,
asset_sum - asset_sum_avg AS asset_sum_diff
FROM last_year_by_day
WHERE date > SYSDATE - x
;
由于某些表达式被重复多次,因此重新考虑查询以避免重复是一个好主意。这是一种方式:
WITH last_year AS
(
SELECT TRUNC(time, 'DD') AS date,
TO_CHAR(time, 'D') AS day_of_week,
count
FROM yourtable
WHERE time > SYSDATE - 365
),
last_year_by_day AS
(
SELECT date,
day_of_week,
SUM(count) AS asset_sum,
AVG(SUM(count)) OVER (PARTITION BY day_of_week) AS asset_sum_avg
FROM last_year
GROUP BY date, day_of_week
)
SELECT date,
day_of_week,
asset_sum,
asset_sum_avg,
asset_sum - asset_sum_avg AS asset_sum_diff
FROM last_year_by_day
WHERE date > SYSDATE - x
;
最后一个注释是关于TO_CHAR('D')
,用于获取day_of_week
值。由于您对相同的结果使用了不同的方法,因此您可能不会意识到TO_CHAR('D')
设置会影响NLS_TERRITORY
的结果。您可能希望使用NLS_TERRITORY
语句将TO_CHAR('D')
设置为导致1
周一返回2
,周二{{1}}等等的值{ {3}}是支持的地区列表。