Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Postgres 9.x在重叠日期加入&;时间范围_Sql_Postgresql_Postgresql 9.1_Postgresql 9.2 - Fatal编程技术网

Sql Postgres 9.x在重叠日期加入&;时间范围

Sql Postgres 9.x在重叠日期加入&;时间范围,sql,postgresql,postgresql-9.1,postgresql-9.2,Sql,Postgresql,Postgresql 9.1,Postgresql 9.2,我有几个表,它们有一个带有时区的时间戳列以及一些附加信息。我需要能够连接这些表,以便每行上的所有信息在给定的日期和时间窗口(在所需的结果集中标记为begin和end)时“有效” 我目前的做法是: 选项#1 创建一个唯一的时间列表 将每个时间点转换为唯一列表(“有效”时间窗口)和每个原始表的时间窗口。[领先(…)超过(…)] 将原始表连接到唯一的时间列表 选项2 将每个时间点(带时区的时间戳)转换为每个表的时间窗口。[领先(…)超过(…)] 连接窗口重叠的表 从每个窗口返回最大值(foo.star

我有几个表,它们有一个带有时区的
时间戳
列以及一些附加信息。我需要能够连接这些表,以便每行上的所有信息在给定的日期和时间窗口(在所需的结果集中标记为
begin
end
)时“有效”

我目前的做法是: 选项#1

  • 创建一个唯一的时间列表
  • 将每个时间点转换为唯一列表(“有效”时间窗口)和每个原始表的时间窗口。[
    领先(…)超过(…)
    ]
  • 将原始表连接到唯一的时间列表
  • 选项2

  • 将每个时间点(
    带时区的时间戳
    )转换为每个表的时间窗口。[
    领先(…)超过(…)
    ]
  • 连接窗口重叠的表
  • 从每个窗口返回
    最大值(foo.start,bar.start)
    最小值(foo.stop,bar.stop)
    ,以找到真正的“有效”窗口
  • 例如: 表格:foo

      fooid  |  description  |       datetime
    ---------|---------------|-----------------------
        1    |   Varsion 1   |  2010-01-01 00:00:00  
        2    |   Varsion 2   |  2010-07-01 00:00:00 
    
    表格:条形图

      barid  |  fooid  |  description  |       datetime
    ---------|---------|---------------|-----------------------
        1    |    1    |   Varsion A   |  2010-01-01 00:00:00
        2    |    1    |   Varsion B   |  2010-02-01 00:00:00
        3    |    1    |   Varsion C   |  2010-03-01 00:00:00
        4    |    1    |   Varsion D   |  2010-04-01 00:00:00
        5    |    1    |   Varsion E   |  2010-05-01 00:00:00
        6    |    1    |   Varsion F   |  2010-06-01 00:00:00
        7    |    2    |   Varsion A   |  2010-07-01 00:00:00
        8    |    2    |   Varsion B   |  2010-08-01 00:00:00
        9    |    2    |   Varsion C   |  2010-09-01 00:00:00
        10   |    2    |   Varsion D   |  2010-10-01 00:00:00
        11   |    2    |   Varsion E   |  2010-11-01 00:00:00
        12   |    2    |   Varsion F   |  2010-12-01 00:00:00
    
    简化的预期结果

            begin          |          end          |  fooid  |   foo_desc    |       foostart        |        foostop        |  barid  |   bar_desc   |       foostart        |        foostop        
    -----------------------|-----------------------|---------|---------------|-----------------------|-----------------------|---------|--------------|-----------------------|-----------------------
             ...           |         ...           |   ...   |      ...      |         ...           |         ...           |   ...   |     ...      |         ...           |         ...           
      2010-05-01 00:00:00  |  2010-06-01 00:00:00  |    1    |   Varsion 1   |  2010-01-01 00:00:00  |  2010-07-01 00:00:00  |    5    |  Varsion E   |  2010-05-01 00:00:00  |  2010-06-01 00:00:00
      2010-06-01 00:00:00  |  2010-07-01 00:00:00  |    1    |   Varsion 1   |  2010-01-01 00:00:00  |  2010-07-01 00:00:00  |    6    |  Varsion F   |  2010-06-01 00:00:00  |        infinity
      2010-07-01 00:00:00  |  2010-08-01 00:00:00  |    2    |   Varsion 2   |  2010-07-01 00:00:00  |       infinity        |    7    |  Varsion A   |  2010-07-01 00:00:00  |  2010-08-01 00:00:00
      2010-08-01 00:00:00  |  2010-09-01 00:00:00  |    2    |   Varsion 2   |  2010-07-01 00:00:00  |       infinity        |    8    |  Varsion B   |  2010-08-01 00:00:00  |  2010-09-01 00:00:00
             ...           |         ...           |   ...   |      ...      |         ...           |         ...           |   ...   |     ...      |         ...           |         ...           
    

    我的问题: 实现这一目标的最佳方式是什么?我已经创建了一个展示两种不同解决方案的示例,我希望听到关于每种解决方案的想法,以及可能的解决方案

    更新#1: 在本例中,只有两个表需要联接。。。然而,在某些情况下,我可能需要连接多个表3、表4或更多

    更新#2: 使用选项#1,我的问题是,当我有大的结果集时,我发现初始子查询可能很大,postgres不能使用索引。这会造成很大的性能损失。另一方面,我发现它是最精确的,因为我可以
    左外连接
    ,并获得相关的
    NULL
    数据

    使用选项#2,查询计划器能够使用带有时区
    列的
    时间戳上的索引;但是,在
    FROM
    子句中,连接两个以上的表变得更加复杂。我可以将
    (table1.start,table1.stop)重叠(table2.start,table2.stop)
    移动到
    WHERE
    子句中,但随后我丢失了相关的
    NULL
    数据

    所有这些让我想知道是否有更好的方法…

    • 为窗口函数和lag()使用默认值,而不是
      coalesce()

    而不是

    COALESCE(LEAD(datetime) OVER (ORDER BY fooid, datetime), 'infinity'::TIMESTAMP) AS stop
    
    • 当您按fooid进行
      分区时,按fooid进行排序是毫无意义的

    而不是:

    (PARTITION BY fooid ORDER BY fooid, datetime)
    
    • 您(或某些工具)双引号引用了每个标识符,即使它们都是合法的,没有引号。使查询更难阅读。放松噪音
    除此之外:你的问题对于stackoverflow来说太宽泛了,而且描述很难理解

    考虑:

    • 为窗口函数和lag()使用默认值,而不是
      coalesce()

    而不是

    COALESCE(LEAD(datetime) OVER (ORDER BY fooid, datetime), 'infinity'::TIMESTAMP) AS stop
    
    • 当您按fooid进行
      分区时,按fooid进行排序是毫无意义的

    而不是:

    (PARTITION BY fooid ORDER BY fooid, datetime)
    
    • 您(或某些工具)双引号引用了每个标识符,即使它们都是合法的,没有引号。使查询更难阅读。放松噪音
    除此之外:你的问题对于stackoverflow来说太宽泛了,而且描述很难理解


    想一想:

    你能把这句话改一下吗?因为在您的示例数据中没有barid 5,6,7,8。还有,这些是审计表,在datetime之前有一个有效的_,对吗?@Denis-对不起,我把ID忘了。。。我已经更新了问题。此外,这更像是一个日志(而不是一个审计表)。每个记录在其创建时间戳时有效,并且在被下一个记录覆盖之前保持有效。fooid是foo的主键。它指向“2010-01-01”日期。现在,食品停止日期“2010-07-01”从何而来?是否有一些内置的6个月需求,或者ist是从无关(IMHO)fooid=2记录继承的?另外:为什么在bar表中有一个fooid(FK)列?请澄清。@joop-是的,fooid是表foo的主键。Fooid2也是Fooid1的终点(这与bar表的配置相同…下一个值是当前时间窗口的结尾。此外,bar表引用了具有fooid的foo表…但不能保证表之间的时间戳一致…因此真正的重点是连接重叠时间。因此,实际上fooid和barid都是surrogate键,并且您要执行的所有匹配都应该基于时间戳?(这由Erwin的回答说明,其中{fooid,barid}从联接中完全省略)你能不能重新表述一下?因为在你的示例数据中没有barid 5,6,7,8。另外,这些是审计表,在datetime之前有一个有效的_,对吗?@Denis-对不起,我没有输入ID…我已经更新了这个问题。而且这更像是一个日志(而不是审计表)。每个记录在其创建时间戳时有效,并在被下一个记录覆盖之前保持有效。fooid是foo的主键。它指向“2010-01-01”日期。现在,foostop日期“2010-07-01”从何而来?是否有内置的6个月要求,或者是从无关(IMHO)继承的fooid=2记录?另外:为什么在bar表中有一个fooid(FK)列?请澄清。@joop-是的,fooid是表foo的主键。fooid 2也是fooid 1的终点(这与bar表的配置相同…下一个值是当前时间窗口的结束。此外,bar表引用了具有fooid的foo表…但不能保证时间戳是正确的。)