繁体   English   中英

如何分组并从特定行获取值

[英]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的回答修订并不需要一个EXISTSLEFT 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;

http://sqlfiddle.com/#!18/3cc52/31

这是一个鸿沟和孤岛的问题-但有开始和结束日期。 我可以通过确定孤岛从哪里开始(使用left joinexists ),然后确定累积和和聚合来实现:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM