SQL统计问题.固定行数变为不固定行数并自动取值的问题

maskdata 2010-01-27 03:36:27
有如下表
StartTime EndTime Price Class
10.1 NULL 1.1 1
10.15 10.18 1.2 1
10.20 NULL 1.3 1
10.25 10.26 1.4 1

如何通过SQL语句得出如下结果(传入统计时间为10.1-10.31)
StartTime EndTime Price Class
10.1 10.15 1.1 1
10.15 10.18 1.2 1
10.18 10.20 1.1 1
10.20 10.25 1.3 1
10.25 10.26 1.4 1
10.26 10.31 1.3 1
...全文
94 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
maskdata 2010-06-30
  • 打赏
  • 举报
回复
非常感谢
ACMAIN_CHM 2010-01-27
  • 打赏
  • 举报
回复
一句SQL的实现方法如下,但从效率上来说,应该由程序或存储过程来实现更多合理。

mysql> select * from t_maskdata;
+------------+------------+-------+-------+
| StartTime | EndTime | Price | Class |
+------------+------------+-------+-------+
| 2009-10-01 | NULL | 1.1 | 1 |
| 2009-10-15 | 2009-10-18 | 1.2 | 1 |
| 2009-10-20 | NULL | 1.3 | 1 |
| 2009-10-25 | 2009-10-26 | 1.4 | 1 |
+------------+------------+-------+-------+
4 rows in set (0.00 sec)

mysql>
mysql> set @x1='2009-10-01';
Query OK, 0 rows affected (0.00 sec)

mysql> set @x2='2009-10-31';
Query OK, 0 rows affected (0.00 sec)

mysql>
mysql> select t.StartTime,
-> COALESCE(
-> b.EndTime,
-> (select min(StartTime) from t_maskdata where StartTime> t.StartTime),
-> @x2
-> ) as EndTime,
-> COALESCE(
-> b.Price,
-> (select Price from t_maskdata where StartTime<t.StartTime and EndTime is null order by StartTime desc limit 1)
-> ) as Price,
-> COALESCE(
-> b.Class,
-> (select Class from t_maskdata where StartTime<t.StartTime and EndTime is null order by StartTime desc limit 1)
-> ) as Class
-> from (
-> select StartTime from t_maskdata
-> union
-> select EndTime from t_maskdata where EndTime is not null
-> union
-> select @x1
-> ) t left join t_maskdata b on t.StartTime=b.StartTime
-> order by 1;
+------------+------------+-------+-------+
| StartTime | EndTime | Price | Class |
+------------+------------+-------+-------+
| 2009-10-01 | 2009-10-15 | 1.1 | 1 |
| 2009-10-15 | 2009-10-18 | 1.2 | 1 |
| 2009-10-18 | 2009-10-20 | 1.1 | 1 |
| 2009-10-20 | 2009-10-25 | 1.3 | 1 |
| 2009-10-25 | 2009-10-26 | 1.4 | 1 |
| 2009-10-26 | 2009-10-31 | 1.3 | 1 |
+------------+------------+-------+-------+
6 rows in set (0.01 sec)

mysql>
maskdata 2010-01-27
  • 打赏
  • 举报
回复
因为我现在已经对开始时间排序好了.而且开始时间和结束时间所包含的时间也不可能交叉重复

所以简单的可以理解为:
上一行的结束时间不等于NULL并且上一行的结束时间和下一行的开始时间不相等
则取上一行的结束时间和下一行的开始时间生成一条新行
该新生的价格取该行上边最近的一个结束时间为NULL的对应的PRICE

如第二条和第三条
10.15-10.18
10.20-10.25
因为10.18不为空而且不等于10.20
所以10.18-10.20组成一个新行.价格取10.18上边最近的结束时间为NULL的那行所对应的价格.即第一条的1.1


所以多出一条26-31是因为其实最后一条最不是以31结束的.而是以26结束的.所以需要补全
maskdata 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 acmain_chm 的回复:]
StartTime  EndTime  Price  Class
10.1      10.15  1.1  1
10.15    10.18  1.2  1
10.18    10.20 1.1  1
10.20    10.25  1.3  1
10.25    10.26  1.4  1
10.26    10.31 1.3  1

这两条的价格怎么来的?
[/Quote]
上一条的结束时间和本条的开始时间不相同.则把他们的之间的时间当新条新增出来...

比如第一条是10.1-永久
第二条是10.15-10.18
第三条是10.20-10.25

有结束时间的内容是优先于无结束时间的.如果被包含则优先取有结束时间的
比如.第二条取出来是15-18.第三条是20-25
那么1-15和18-20都是都符合1-永久.所以取1-永久相关的价格
lilinew 2010-01-27
  • 打赏
  • 举报
回复
前一行的 EndTime取后裔行的StartTime
ACMAIN_CHM 2010-01-27
  • 打赏
  • 举报
回复
StartTime EndTime Price Class
10.1 10.15 1.1 1
10.15 10.18 1.2 1
10.18 10.20 1.1 1
10.20 10.25 1.3 1
10.25 10.26 1.4 1
10.26 10.31 1.3 1

这两条的价格怎么来的?
WWWWA 2010-01-27
  • 打赏
  • 举报
回复
10.18 10.20 1.1 1
10.26 10.31 1.3 1
简要说明一下结果是怎样得出的
lilinew 2010-01-27
  • 打赏
  • 举报
回复
存储过程 如果有游标 是很简单

否则 加1个id 埂新完再去掉这个id (还是要用游标)

不用游标 用动态sql ?? (这个不知道哦阿)

56,679

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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