SQL-日期范围中缺少时间

SQL-日期范围中缺少时间,sql,postgresql,date-range,gaps-and-islands,Sql,Postgresql,Date Range,Gaps And Islands,我有一张表中的数据显示点火是真是假 我编写了一个SQL查询,显示日期期间的点火状态 SELECT min(date) as date_from, max(date) as date_to, ignition FROM (SELECT date, ignition, row_number() over (order by date) as seqnum, row_number() over (partition by i

我有一张表中的数据显示点火是真是假

我编写了一个SQL查询,显示日期期间的点火状态

SELECT min(date) as date_from, max(date) as date_to, ignition
FROM (SELECT date,
             ignition,
             row_number() over (order by date) as seqnum,
             row_number() over (partition by ignition order by date) as seqnum_s
      FROM table_data
      WHERE date >= '2019-06-01T21:00:00.000Z' AND date <= '2019-06-09T20:59:59.999Z'
    ) as raw_data
GROUP BY (seqnum - seqnum_s), ignition
ORDER BY min(date);
但结果中缺少10:30到11:30的日期和11:30到11:45的日期。我应该买这个:

|---------------------------|----------------------------|----------|
|             date_from     | date_to                    | ignition |
|---------------------------|----------------------------|----------|
|2019-06-03 10:15:00.000000 | 2019-06-03 11:30:00.000000 | false    |
|---------------------------|----------------------------|----------|
|2019-06-03 11:30:00.000000 | 2019-06-03 11:45:00.000000 | true     |
|---------------------------|----------------------------|----------|
|2019-06-03 11:45:00.000000 | 2019-06-03 11:55:00.000000 | false    |
|---------------------------|----------------------------|----------|

问题是,在聚合到一个块中时,例如,在false的5行之后,他只查看false的最后一行,以确定块的结束时间,而不是第一行之后的第一行,即第一行为true,然后将该值设置到当前行的date_中,SQL如下所示:

select 
    date_from,
    case when lead(date_from,1) over(order by date_from) is null then date_to else lead(date_from,1) over(order by date_from) end as date_to,
    ignition
from (
SELECT min(date) as date_from, max(date) as date_to, ignition
FROM (SELECT date,
             ignition,
             row_number() over (order by date) as seqnum,
             row_number() over (partition by ignition order by date) as seqnum_s
      FROM table_data
      WHERE date >= '2019-06-01T21:00:00.000Z' AND date <= '2019-06-09T20:59:59.999Z'
    ) as raw_data
GROUP BY (seqnum - seqnum_s), ignition
ORDER BY min(date)
) tmp;
      date_from      |       date_to       | ignition 
---------------------+---------------------+----------
 2019-06-03 10:15:00 | 2019-06-03 11:30:00 | f
 2019-06-03 11:30:00 | 2019-06-03 11:45:00 | t
 2019-06-03 11:45:00 | 2019-06-03 11:55:00 | f
(3 rows)

一种更简单的表达方式是:

SELECT min(date) as date_from,
       lead(min(date)) over (order by min(date)) as date_to,
       ignition
FROM (SELECT d.*,
             row_number() over (order by date) as seqnum,
             row_number() over (partition by ignition order by date) as seqnum_s
      FROM table_data d
      WHERE date >= '2019-06-01T21:00:00.000Z' AND date < '2019-06-09T21:00:00Z'
     ) as raw_data
GROUP BY (seqnum - seqnum_s), ignition
ORDER BY min(date)
您两次使用row_编号的方法非常巧妙,这帮助解决了我的一个历史问题。谢谢!:D
select 
    date_from,
    case when lead(date_from,1) over(order by date_from) is null then date_to else lead(date_from,1) over(order by date_from) end as date_to,
    ignition
from (
SELECT min(date) as date_from, max(date) as date_to, ignition
FROM (SELECT date,
             ignition,
             row_number() over (order by date) as seqnum,
             row_number() over (partition by ignition order by date) as seqnum_s
      FROM table_data
      WHERE date >= '2019-06-01T21:00:00.000Z' AND date <= '2019-06-09T20:59:59.999Z'
    ) as raw_data
GROUP BY (seqnum - seqnum_s), ignition
ORDER BY min(date)
) tmp;
      date_from      |       date_to       | ignition 
---------------------+---------------------+----------
 2019-06-03 10:15:00 | 2019-06-03 11:30:00 | f
 2019-06-03 11:30:00 | 2019-06-03 11:45:00 | t
 2019-06-03 11:45:00 | 2019-06-03 11:55:00 | f
(3 rows)
SELECT min(date) as date_from,
       lead(min(date)) over (order by min(date)) as date_to,
       ignition
FROM (SELECT d.*,
             row_number() over (order by date) as seqnum,
             row_number() over (partition by ignition order by date) as seqnum_s
      FROM table_data d
      WHERE date >= '2019-06-01T21:00:00.000Z' AND date < '2019-06-09T21:00:00Z'
     ) as raw_data
GROUP BY (seqnum - seqnum_s), ignition
ORDER BY min(date)