cte结合partition - 一道复杂的sql面试题
2012-07-12 12:03
411 查看
今天别人问了我一道复杂的sql面试题, 题目是这样的:
--code 价格 时间
'0010' 100 '2012-08-01 00:00:00.000'
'0010' 100 '2012-08-02 00:00:00.000'
'0010' 100 '2012-08-03 00:00:00.000'
'0010' 100 '2012-08-05 00:00:00.000'
'0012' 120 '2012-08-07 00:00:00.000'
'0012' 120 '2012-08-08 00:00:00.000'
上面是原始数据集,
由上面的数据集,根据时间连续原则, 需要得到下面的结果集
--结果集
--code 价格 开始时间 结束时间
'0010' 100 '2012-08-01' '2012-08-03'
'0010' 100 '2012-08-05' '2012-08-05'
'0012' 120 '2012-08-07' '2012-08-08'
建表语句如下:
CREATE TABLE [dbo].[MyOrder](
[code] [varchar](10) NULL,
[price] [int] NULL,
[time] [datetime] NULL
) ON [PRIMARY]
GO
解决代码如下, 一会儿再给你分析我的思路
with cteMinOrder
as
(
select code, MIN(time) as min_time
from MyOrder
group by code
),
cteMyOrder
as
(
SELECT *, Rank()
Over(Partition by code Order BY time) AS rownum
FROM MyOrder
),
cteCompOrder
as
(
select a.code, a.price, a.time, a.rownum,
b.min_time, DATEADD(day, rownum - 1, b.min_time) AS ctime
from cteMyOrder a left join cteMinOrder b
on a.code = b.code
)
select code, price, MIN(time) as start_time, MAX(time) as end_time
from cteCompOrder
where time=ctime
group by code, price
union all
select code, price, MIN(time) as start_time, MAX(time) as end_time
from cteCompOrder
where time!=ctime
group by code, price
order by code
--code 价格 时间
'0010' 100 '2012-08-01 00:00:00.000'
'0010' 100 '2012-08-02 00:00:00.000'
'0010' 100 '2012-08-03 00:00:00.000'
'0010' 100 '2012-08-05 00:00:00.000'
'0012' 120 '2012-08-07 00:00:00.000'
'0012' 120 '2012-08-08 00:00:00.000'
上面是原始数据集,
由上面的数据集,根据时间连续原则, 需要得到下面的结果集
--结果集
--code 价格 开始时间 结束时间
'0010' 100 '2012-08-01' '2012-08-03'
'0010' 100 '2012-08-05' '2012-08-05'
'0012' 120 '2012-08-07' '2012-08-08'
建表语句如下:
CREATE TABLE [dbo].[MyOrder](
[code] [varchar](10) NULL,
[price] [int] NULL,
[time] [datetime] NULL
) ON [PRIMARY]
GO
解决代码如下, 一会儿再给你分析我的思路
with cteMinOrder
as
(
select code, MIN(time) as min_time
from MyOrder
group by code
),
cteMyOrder
as
(
SELECT *, Rank()
Over(Partition by code Order BY time) AS rownum
FROM MyOrder
),
cteCompOrder
as
(
select a.code, a.price, a.time, a.rownum,
b.min_time, DATEADD(day, rownum - 1, b.min_time) AS ctime
from cteMyOrder a left join cteMinOrder b
on a.code = b.code
)
select code, price, MIN(time) as start_time, MAX(time) as end_time
from cteCompOrder
where time=ctime
group by code, price
union all
select code, price, MIN(time) as start_time, MAX(time) as end_time
from cteCompOrder
where time!=ctime
group by code, price
order by code
相关文章推荐
- 一道看上去很吓人的算法面试题:如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)
- 一道经典的sql面试题不同的写法
- 记一道巨简单,但是我没有答上来的Sql面试题
- 一道经典的SQL面试题
- 一道sql面试题
- 一道面试题:请写sql查询出,成绩小于60的同学的姓名和平均分,并按平均分排序
- 一道看上去很吓人的算法面试题:如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)
- 关于一道sql的面试题 (非常精典)
- 一道看上去很吓人的算法面试题:如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)
- 一道sql 关于pivot的面试题
- 一道sql面试题附答案
- 一道sql面试题的解答
- 开始学习SQL了,请高手回答帮一下小菜鸟,一道面试题
- 一道递增的sql面试题
- 一道SQL语句面试题
- 一道易错的SQL面试题
- 一道SQL面试题
- 一道看上去很吓人的算法面试题:如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)
- 一道关于sql的面试题
- 一道看上去很吓人的算法面试题:如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)