我有这张原始表:
type startDate endDate eatingDate
1 2011 2012 1979
1 2012 2013 1980
1 2013 2014 NULL
2 2014 2015 1982
3 2015 2016 1983
1 2016 2017 1984
1 2017 2018 1985
这是我想要的结果:
type startDate endDate eatingDate
1 2011 2014 NULL
2 2014 2015 1982
3 2015 2016 1983
1 2016 2018 1985
我想解决的另一个案例是,在eatDate原始表格的第3行中,值为1981,结果将是:
type startDate endDate eatingDate
1 2011 2014 1981
2 2014 2015 1982
3 2015 2016 1983
1 2016 2018 1985
注意:具有相同类型的行数未知。
答案 0 :(得分:1)
我会分三步完成。
使用"隔离岛屿"方法,分配"组标识符"到每个连续的行组。
使用分析功能挑选出您感兴趣的EatingDate。
然后将每个组的所有内容聚合为一行。
WITH
grouped
AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY startDate)
-
ROW_NUMBER() OVER (PARTITION BY type ORDER BY startDate) AS groupID,
*
FROM
eating
),
analysed
AS
(
SELECT
*,
FIRST_VALUE(eatingDate) OVER (PARTITION BY type, groupID ORDER BY startDate DESC) AS lastEatingDate
FROM
grouped
)
SELECT
type,
MIN(startDate ) AS startDate,
MAX(endDate ) AS endDate,
MAX(lastEatingDate) AS lastEatingDate
FROM
analysed
GROUP BY
type,
groupID
ORDER BY
MIN(startDate)
http://sqlfiddle.com/#!18/3cc52/6
<强> 编辑: 强>
通过使用EXISTS
代替(降低总体费用),修订了@ GordonLinoff的答案,不需要LEFT JOIN
或LAG
。
此版本并不假设一行的endDate
始终等于后续行的startDate
。
SELECT DISTINCT
type,
MIN(startDate ) OVER (PARTITION BY grp ) AS startDate,
MAX(endDate ) OVER (PARTITION BY grp ) AS endDate,
FIRST_VALUE(eatingDate) OVER (PARTITION BY grp ORDER BY startDate DESC) AS last_eatingdate
FROM
(
SELECT
e.*,
SUM(isStart) OVER (ORDER BY startDate DESC) as grp
FROM
(
SELECT
*,
CASE WHEN LAG(type) OVER (ORDER BY startDate DESC) = type THEN 0 ELSE 1 END AS isStart
FROM
eating
) e
) e
ORDER BY
startDate;
答案 1 :(得分:1)
这是一个差距和岛屿问题 - 但有开始和结束日期。我会通过识别岛屿的起点(使用left join
或exists
)然后累积总和和聚合来做到这一点:
select distinct type,
min(startDate) over (partition by type, grp) as startDate,
max(endDate) over (partition by type, grp) as endDate,
first_value(eatingDate) over (partition by type, grp order by startDate desc) as last_eatingdate
from (select e.*,
sum(isStart) over (partition by type order by startDate) as grp
from (select e.*,
(case when e2.type is null then 1 else 0 end) as isStart
from eating e left join
eating e2
on e.startdate = e2.enddate and e.type = e2.type
) e
) e
order by type, startDate;
Here是SQL小提琴。