超难SQL求助,对连续时间区域分组求和

kingofworl 2009-09-03 10:15:38
模拟数据如下:
20090901 10
20090902 20
20090903 7
20090904 5
20090906 5
20090908 5

要求每相邻的两天作为一个单位统计,不能连续单天统计
结果如下
20090901+20090902 30
20090903+20090904 12
20090906+20090907 5
20090908+20090909 5
请大家不吝赐教,拿出可行方案者另有分谢
...全文
888 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
luoyoumou 2009-09-11
  • 打赏
  • 举报
回复
楼上的:用过SQL Plus没?

你可以把
SQL> 变成 贾瑞民> 但不会影响你在里面执行任何语句
bai_jiong 2009-09-10
  • 打赏
  • 举报
回复
先记下
jiaruimin11 2009-09-10
  • 打赏
  • 举报
回复
scott@ORCL10G 是什么意思.请解释一下.
xlfd2005 2009-09-10
  • 打赏
  • 举报
回复
select trunc((rownum-1)/2) no, sum(n),
replace(wmsys.wm_concat(to_char(d,'yyyymmdd')),',','+') title
from
(select d, n from test_a order by d asc) t
group by trunc((rownum-1)/2)
order by trunc((rownum-1)/2)
luoyoumou 2009-09-10
  • 打赏
  • 举报
回复
scott@ORCL10G> CREATE TABLE test_tb(
2 Datetime1 DATE,
3 Datetime2 DATE,
4 Dategroup VARCHAR2(30),
5 Num NUMBER(7,0));

表已创建。

scott@ORCL10G>
scott@ORCL10G> INSERT INTO test_tb(Datetime1, Num)
2 VALUES(TO_DATE('20090901','yyyymmdd'), 10);

已创建 1 行。

scott@ORCL10G> INSERT INTO test_tb(Datetime1, Num)
2 VALUES(TO_DATE('20090902','yyyymmdd'), 20);

已创建 1 行。

scott@ORCL10G> INSERT INTO test_tb(Datetime1, Num)
2 VALUES(TO_DATE('20090903','yyyymmdd'), 7);

已创建 1 行。

scott@ORCL10G> INSERT INTO test_tb(Datetime1, Num)
2 VALUES(TO_DATE('20090904','yyyymmdd'), 5);

已创建 1 行。

scott@ORCL10G> INSERT INTO test_tb(Datetime1, Num)
2 VALUES(TO_DATE('20090906','yyyymmdd'), 5);

已创建 1 行。

scott@ORCL10G> INSERT INTO test_tb(Datetime1, Num)
2 VALUES(TO_DATE('20090908','yyyymmdd'), 5);

已创建 1 行。

scott@ORCL10G>
scott@ORCL10G> SELECT * FROM test_tb;

DATETIME1 DATETIME2 DATEGROUP NUM
-------------- -------------- ------------------------------ ----------
01-9月 -09 10
02-9月 -09 20
03-9月 -09 7
04-9月 -09 5
06-9月 -09 5
08-9月 -09 5

已选择6行。

scott@ORCL10G>
scott@ORCL10G> UPDATE test_tb SET Datetime2=Datetime1;

已更新6行。

scott@ORCL10G>
scott@ORCL10G> SELECT * FROM test_tb;

DATETIME1 DATETIME2 DATEGROUP NUM
-------------- -------------- ------------------------------ ----------
01-9月 -09 01-9月 -09 10
02-9月 -09 02-9月 -09 20
03-9月 -09 03-9月 -09 7
04-9月 -09 04-9月 -09 5
06-9月 -09 06-9月 -09 5
08-9月 -09 08-9月 -09 5

已选择6行。

scott@ORCL10G>
scott@ORCL10G> UPDATE test_tb SET Dategroup=
2 TO_CHAR(TO_DATE(TO_CHAR(CASE WHEN MOD(TO_CHAR(Datetime1,'dd'),2)<>'0' THEN Datetime2+1 ELSE Dat
etime2 END,'yyyymmdd'),'yyyymmdd')-1,'yyyymmdd')
3 ||'+'||TO_CHAR(CASE WHEN MOD(TO_CHAR(Datetime1,'dd'),2)<>'0' THEN Datetime2+1 ELSE Datetime2 EN
D,'yyyymmdd');

已更新6行。

scott@ORCL10G>
scott@ORCL10G> UPDATE test_tb SET Dategroup=TO_CHAR(Datetime1,'yyyymmdd')
2 WHERE Dategroup IN (SELECT Dategroup FROM test_tb GROUP BY Dategroup HAVING COUNT(Dategroup)=1)
;

已更新2行。

scott@ORCL10G>
scott@ORCL10G> SELECT * FROM test_tb;

DATETIME1 DATETIME2 DATEGROUP NUM
-------------- -------------- ------------------------------ ----------
01-9月 -09 01-9月 -09 20090901+20090902 10
02-9月 -09 02-9月 -09 20090901+20090902 20
03-9月 -09 03-9月 -09 20090903+20090904 7
04-9月 -09 04-9月 -09 20090903+20090904 5
06-9月 -09 06-9月 -09 20090906 5
08-9月 -09 08-9月 -09 20090908 5

已选择6行。

scott@ORCL10G>
scott@ORCL10G> SELECT Dategroup, SUM(Num) AS SUM_Num
2 FROM test_tb
3 GROUP BY Dategroup
4 ORDER BY SUM(Num) DESC;

DATEGROUP SUM_NUM
------------------------------ ----------
20090901+20090902 30
20090903+20090904 12
20090906 5
20090908 5

已选择4行。

scott@ORCL10G>
luoyoumou 2009-09-10
  • 打赏
  • 举报
回复
scott@ORCL10G> CREATE TABLE test_tb(
2 NO NUMBER(3,0),
3 Datetime1 DATE,
4 Datetime2 DATE,
5 Dategroup VARCHAR2(30),
6 Num NUMBER(7,0));

表已创建。

scott@ORCL10G> INSERT INTO test_tb(Datetime1, Num)
2 VALUES(TO_DATE('20090901','yyyymmdd'), 10);

已创建 1 行。

scott@ORCL10G> INSERT INTO test_tb(Datetime1, Num)
2 VALUES(TO_DATE('20090902','yyyymmdd'), 20);

已创建 1 行。

scott@ORCL10G> INSERT INTO test_tb(Datetime1, Num)
2 VALUES(TO_DATE('20090903','yyyymmdd'), 7);

已创建 1 行。

scott@ORCL10G> INSERT INTO test_tb(Datetime1, Num)
2 VALUES(TO_DATE('20090904','yyyymmdd'), 5);

已创建 1 行。

scott@ORCL10G> INSERT INTO test_tb(Datetime1, Num)
2 VALUES(TO_DATE('20090906','yyyymmdd'), 5);

已创建 1 行。

scott@ORCL10G> INSERT INTO test_tb(Datetime1, Num)
2 VALUES(TO_DATE('20090908','yyyymmdd'), 5);

已创建 1 行。

scott@ORCL10G>
scott@ORCL10G> SELECT * FROM test_tb;

NO DATETIME1 DATETIME2 DATEGROUP NUM
---------- -------------- -------------- ------------------------------ ----------
01-9月 -09 10
02-9月 -09 20
03-9月 -09 7
04-9月 -09 5
06-9月 -09 5
08-9月 -09 5

已选择6行。

scott@ORCL10G>
scott@ORCL10G> UPDATE test_tb SET Datetime2=Datetime1;

已更新6行。

scott@ORCL10G>
scott@ORCL10G> SELECT * FROM test_tb;

NO DATETIME1 DATETIME2 DATEGROUP NUM
---------- -------------- -------------- ------------------------------ ----------
01-9月 -09 01-9月 -09 10
02-9月 -09 02-9月 -09 20
03-9月 -09 03-9月 -09 7
04-9月 -09 04-9月 -09 5
06-9月 -09 06-9月 -09 5
08-9月 -09 08-9月 -09 5

已选择6行。

scott@ORCL10G>
scott@ORCL10G> UPDATE test_tb SET Dategroup=
2 TO_CHAR(TO_DATE(TO_CHAR(CASE WHEN MOD(TO_CHAR(Datetime1,'dd'),2)<>'0' THEN Datetime2+1 ELSE Dat
etime2 END,'yyyymmdd'),'yyyymmdd')-1,'yyyymmdd')
3 ||'+'||TO_CHAR(CASE WHEN MOD(TO_CHAR(Datetime1,'dd'),2)<>'0' THEN Datetime2+1 ELSE Datetime2 EN
D,'yyyymmdd');

已更新6行。

scott@ORCL10G>
scott@ORCL10G> SELECT * FROM test_tb;

NO DATETIME1 DATETIME2 DATEGROUP NUM
---------- -------------- -------------- ------------------------------ ----------
01-9月 -09 01-9月 -09 20090901+20090902 10
02-9月 -09 02-9月 -09 20090901+20090902 20
03-9月 -09 03-9月 -09 20090903+20090904 7
04-9月 -09 04-9月 -09 20090903+20090904 5
06-9月 -09 06-9月 -09 20090905+20090906 5
08-9月 -09 08-9月 -09 20090907+20090908 5

已选择6行。

scott@ORCL10G>
scott@ORCL10G> SELECT Dategroup, SUM(Num) AS SUM_Num
2 FROM test_tb
3 GROUP BY Dategroup
4 ORDER BY SUM(Num) DESC;

DATEGROUP SUM_NUM
------------------------------ ----------
20090901+20090902 30
20090903+20090904 12
20090905+20090906 5
20090907+20090908 5

已选择4行。

scott@ORCL10G>
小灰狼W 2009-09-08
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 wildwave 的回复:]
改成3天的话挺麻烦,这个语句是基于判断连续性上设计的
如果变成3天,那么例中0904-0906应该排到一起
结果要变成
20090901+20090902+20090903  37
20090904+20090905+20090906  10
20090908+20090909+20090910  5
对吧,按原来的思路行不通
我再想想
[/Quote]

3个的话用一条sql想不出来符合要求的分组办法..
能想到只有:先把日期全部列出来,与原表连接
然后将不符合条件的记录删掉,比如20090907这条记录
然后再3个一组进行分组
小灰狼W 2009-09-08
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 wildwave 的回复:]
改成3天的话挺麻烦,这个语句是基于判断连续性上设计的
如果变成3天,那么例中0904-0906应该排到一起
结果要变成
20090901+20090902+20090903  37
20090904+20090905+20090906  10
20090908+20090909+20090910  5
对吧,按原来的思路行不通
我再想想
[/Quote]

3个的话用一条sql想不出来符合要求的分组办法..
能想到只有:先把日期全部列出来,与原表连接
然后将不符合条件的记录删掉,比如20090907这条记录
然后再3个一组进行分组
mark620 2009-09-08
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 kingofworl 的回复:]
引用 11 楼 shiyiwan 的回复:
那么问题个问题:
模拟数据如下:
20090901    10
20090902    20
20090903    7
20090904    5
20090906    5
20090908    5
20090909    4

该如何统计?像这样吗?
20090901+20090902
20090903+20090904
20090906
20090908+20090909
[/Quote]
恩 这个可以。
小灰狼W 2009-09-08
  • 打赏
  • 举报
回复
改成3天的话挺麻烦,这个语句是基于判断连续性上设计的
如果变成3天,那么例中0904-0906应该排到一起
结果要变成
20090901+20090902+20090903 37
20090904+20090905+20090906 10
20090908+20090909+20090910 5
对吧,按原来的思路行不通
我再想想
xugh 2009-09-08
  • 打赏
  • 举报
回复
为什么一定要一句sql解决呢?
程序不是万能的,sql也不是万能的,最好两者结合一下
kingofworl 2009-09-08
  • 打赏
  • 举报
回复
没好的办法就算了,结贴了
shiyiwan 2009-09-07
  • 打赏
  • 举报
回复
trunc((rn-1)/2)

->
floor((rn-1)/3)
kingofworl 2009-09-07
  • 打赏
  • 举报
回复
不管能不能实现3天统计,等你回复我就结贴了
kingofworl 2009-09-07
  • 打赏
  • 举报
回复
wildwave 兄,照上面那样如果改成统计3天能改吗?
row_number()over(partition by to_date(a,'YYYYMMDD')-rownum order by a)rn,
你的这个用法我以前没用过,学习了
kingofworl 2009-09-07
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 shiyiwan 的回复:]
那么问题个问题:
模拟数据如下:
20090901    10
20090902    20
20090903    7
20090904    5
20090906    5
20090908    5
20090909    4

该如何统计?像这样吗?
20090901+20090902
20090903+20090904
20090906
20090908+20090909
[/Quote]
对 实际上就是这样统计,语句等我下午试验一下
小灰狼W 2009-09-07
  • 打赏
  • 举报
回复
select case when length(a)=8 then a||'+'||to_char(to_date(a,'yyyymmdd')+1,'yyyymmdd')
else replace(a,',','+') end a,b from(
select wm_concat(a)a,sum(b)b from(
select a,b,
row_number()over(partition by to_date(a,'YYYYMMDD')-rownum order by a)rn,
dense_rank()over(order by to_date(a,'YYYYMMDD')-rownum)dk
from (
select * from test_p order by a) )
group by dk,trunc((rn-1)/2))

select * from test_p

A B
20090901 10
20090902 20
20090903 7
20090904 5
20090906 5
20090908 5


A B
20090901+20090902 30
20090903+20090904 12
20090906+20090907 5
20090908+20090909 5
小灰狼W 2009-09-07
  • 打赏
  • 举报
回复
select case when length(a)=8 then a||'+'||to_char(to_date(a,'yyyymmdd')+1,'yyyymmdd')
else replace(a,',','+') end a,b from(
select wm_concat(a)a,sum(b)b from(
select a,b,
row_number()over(partition by to_date(a,'YYYYMMDD')-rownum order by a)rn,
dense_rank()over(order by to_date(a,'YYYYMMDD')-rownum)dk
from (
select * from test_p order by a) )
group by dk,trunc((rn-1)/2))

A B
20090901+20090902 30
20090903+20090904 12
20090906+20090907 5
20090908+20090909 5

楼主看看这样对不
小灰狼W 2009-09-07
  • 打赏
  • 举报
回复
..
去不去掉对结果没什么影响
不过在楼主的例子中,那个是要补上的
shiyiwan 2009-09-07
  • 打赏
  • 举报
回复
#14改下最外层select去掉||'+'||to_char(to_date(a,'yyyymmdd')+1,'yyyymmdd')
就符合了
[Quote=引用 15 楼 kingofworl 的回复:]
引用 11 楼 shiyiwan 的回复:
那么问题个问题:
模拟数据如下:
20090901    10
20090902    20
20090903    7
20090904    5
20090906    5
20090908    5
20090909    4

该如何统计?像这样吗?
20090901+20090902
20090903+20090904
20090906
20090908+20090909

对 实际上就是这样统计,语句等我下午试验一下
[/Quote]
加载更多回复(12)

17,082

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧