[英]How to group by and getting values from specific rows
我有这个原始表:
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
我想解决的另一种情况是,在eatingDate原始表的第3行中,该值为1981,因此结果将是:
type startDate endDate eatingDate
1 2011 2014 1981
2 2014 2015 1982
3 2015 2016 1983
1 2016 2018 1985
注意:具有相同类型的行数是未知的。
我将分三步进行。
使用“空白”方法,为每个连续的行组分配“组标识符”。
使用分析功能可以选择您感兴趣的EateDate。
然后将所有内容汇总到每组一行。
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
编辑:
动@ GordonLinoff的回答修订并不需要一个EXISTS
或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;
这是一个鸿沟和孤岛的问题-但有开始和结束日期。 我可以通过确定孤岛从哪里开始(使用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;
这是SQL Fiddle。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.