我有一个sql命令,可以在以下列中显示结果
start_date, end_date, count, weekday
对于每个start_date,我想得到从start_date到其工作日匹配的end_date的计数总和。
例如,如果我有一行start_date = 2012 01 01
和end_date = 2012 08 08
以及weekday = Tuesday
,我想找到所有其他行,其start_date属于该范围内它是星期二,然后找到计数的总和。我怎样才能做到这一点?
E.g。从这张表
Start || End ||Count|| Weekday
2012-01-01 || 2012-12-12 || 5 || Tuesday
2012-05-05 || 2012-12-12 || 7 || Tuesday
2012-06-06 || 2012-10-10 || 2 || Wednesday
2012-07-07 || 2012-08-08 || 8 || Wednesday
2012-09-09 || 2012-10-10 || 9 || Tuesday
它应该返回
date | sum_count
2012-01-01 | 16 // count of 2012-05-05 + 2012-09-09 (Tuesdays only)
2012-05-05 | 9
2012-06-06 | 8
2012-07-07 | 0
2012-09-09 | 0
答案 0 :(得分:1)
没有小提琴,sqlfiddle.com第一次尝试就很难正确。但是你想要做的就是这样做:
select count(*), *
from
(
select *
from
(
select start_date,end_date,weekday
from table
where start_date >= timestamp('2012 01 01')
and end_date <= timestamp('2012 08 08')
)
where weekday = 'Tuesday'
);
目标是每次都减少结果集,方法是将weekday
保留在单独的子查询中,以避免代价高昂的加入或2。
问题
是吗?我仍然不明白。 2012 08 08,2012 01 01和 星期二来自输入表,我有多行 需要处理。你是说分别处理每一行是 效率更高?
您必须单独处理每一行,除非您知道在搜索日期时要避免全表扫描。这取决于比较我们没有的解释计划,因为我们还在等待你的小提琴 关键是,最内部的查询将为您提供所需的日期范围,以及一周中的所有日期。它更有效(大多数时候),然后针对更具体的where子句执行,在您的情况下是星期几。原因是数据库(大多数现代数据库)尝试以尽可能快地返回的方式对数据进行排序。
额外更新
作为一个真实世界的例子,我有一个表格,其中包含大约10亿个条目,我必须运行一个分析函数。我这样做的第一种方式是:
select *
from
(
select *, row_number() over (partition by id order by seen desc) rn
from foo
)where rn =1
and status = 1
以上大约需要9分钟才能执行。当我将查询修改为:
select *
from
( select *
from
(
select *, row_number() over (partition by id order by seen desc) rn
from foo
)where status = 1
) where status = 1
它在不到1分钟内返回。这是一个例子,我小心地减小了驱动结果集的大小,这样系统可以减少工作量,从而更快地返回。
答案 1 :(得分:1)
试试这个,我相信自我加入是最好的选择
select b.start_date,nvl(sum(a.Count),0) from TABLE2 a right join TABLE2 b on
a.start_date<>b.start_date and
a.weekday=b.weekday and a.start_date between b.start_date and b.end_date
group by b.start_date order by b.start_date
答案 2 :(得分:1)
我希望这是你的要求......这个用你的样本数据在oracle中运行
select TAB.START_DATE START_DATE, nvl(X1.SUM_COUNT,0) SUM_COUNT
from TABLE2 TAB,
( select A1.START_DATE,SUM(A2.COUNT) SUM_COUNT
from TABLE2 A1,TABLE2 A2
where A1.WEEKDAY=A2.WEEKDAY and A1.rowid <> A2.rowid
and A2.START_DATE between A1.START_DATE and A1.END_DATE
group by A1.START_DATE
) X1
where TAB.START_DATE=X1.START_DATE(+) order by 1
请参考这个sql小提琴:http://sqlfiddle.com/#!4/2019f/4