【问题标题】:Postgres SQL group by overlapping periodsPostgresql 按重叠时段分组
【发布时间】:2017-07-18 15:45:06
【问题描述】:

我尝试按重叠时段对数据进行分组,如果它们完全覆盖更大的时段,则只保留较小的时段。

所以一个例子会更清楚。 让我们假设这个结构和数据

drop table chload.testdata
create table chload.testdata
( 
  id int,
  startdate date,  
  enddate date,
  val text
);

insert into chload.testdata (id,startdate,enddate,val) values
-- included periods
(1, to_date('2009-01-01','YYYY-MM-DD'), to_date('2010-01-01','YYYY-MM-DD'), 'incA'),
(2, to_date('2010-01-01','YYYY-MM-DD'), to_date('2011-01-01','YYYY-MM-DD'), 'incB'),
(3, to_date('2011-01-01','YYYY-MM-DD'), to_date('2012-01-01','YYYY-MM-DD'), 'incC'),

-- isolated period
(4, to_date('2008-01-01','YYYY-MM-DD'), to_date('2009-01-01','YYYY-MM-DD'), 'isoD'),

-- Covering periods
(5, to_date('2009-01-01','YYYY-MM-DD'), to_date('2011-01-01','YYYY-MM-DD'), 'covE'),
(6, to_date('2009-01-01','YYYY-MM-DD'), to_date('2012-01-01','YYYY-MM-DD'), 'covF')
;

现在的游戏就是要得到那个结果

2009-01-01  2010-01-01  incA covE covF
2010-01-01  2011-01-01  incB covE covF
2011-01-01  2012-01-01  incC covF
2008-01-01  2009-01-01  isoD

注意:如果涵盖期间完全被包含期间“涵盖”,则不会显示涵盖期间。

提前致谢:)

【问题讨论】:

  • 你自己尝试过什么?

标签: sql postgresql group-by postgresql-9.3 overlap


【解决方案1】:

尝试使用这个

SELECT distinct lg1.startdate, lg1.enddate, lg1.val || ' '|| lg2.val
  FROM testdata lg1,testdata lg2
where  lg1.enddate<= lg2.enddate and  lg1.startdate>= lg2.startdate and  lg1.id!= lg2.id
order by 3

【讨论】:

  • 您好,感谢您的帮助。这可能是一个解决方案。但是,我还需要获得隔离期,并且我还可以获得许多“覆盖期”。我刚刚修改了示例以更好地反映这一点。
【解决方案2】:

尝试使用这个

WITH enddates AS
  (SELECT DISTINCT lg1.startdate,
                   lg1.enddate,
                   lg1.val AS pg,
                   string_agg(lg2.val,' ') AS RESULT
   FROM chload.testdata lg1,
        chload.testdata lg2
   WHERE (lg1.enddate<= lg2.enddate
          AND lg1.startdate>= lg2.startdate
          AND lg1.id!= lg2.id
          AND lg1.val NOT IN
            (SELECT lg2.val
             FROM chload.testdata lg1,
                  chload.testdata lg2
             WHERE lg1.enddate<= lg2.enddate
               AND lg1.startdate>= lg2.startdate
               AND lg1.id!= lg2.id))
   GROUP BY 1,
            2,
            3
   ORDER BY 3)
SELECT DISTINCT startdate,
                enddate,
                pg,
                pg||' '|| RESULT AS RESULT
FROM enddates
UNION ALL
SELECT lg.startdate,
       lg.enddate,
       lg.val AS pg,
       lg.val AS RESULT
FROM chload.testdata lg
WHERE lg.val NOT IN
    (SELECT lg1.val
     FROM chload.testdata lg1,
          chload.testdata lg2
     WHERE lg1.enddate<= lg2.enddate
       AND lg1.startdate>= lg2.startdate
       AND lg1.id!= lg2.id)
  AND lg.val NOT IN
    (SELECT lg2.val
     FROM chload.testdata lg1,
          chload.testdata lg2
     WHERE lg1.enddate<= lg2.enddate
       AND lg1.startdate>= lg2.startdate
       AND lg1.id!= lg2.id)
ORDER BY 3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 2021-04-13
    • 2011-10-13
    • 2019-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多