cte结合partition 一道复杂的sql面试题

今天别人问了我一道复杂的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](10NULL,
    [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
技术改变世界
原文地址:https://www.cnblogs.com/davidgu/p/2587858.html