【问题标题】:How to get closest date for specific rows in postgresql如何获取postgresql中特定行的最接近日期
【发布时间】:2017-01-01 10:49:09
【问题描述】:

我有以下问题:

我有一个包含两种类型数据的表。一个状态 = 1,一个状态 = 2。对于状态 = 2 的每一行,我需要状态 = 1 的最后一个对应日期。这是一个示例:

date           state    id
'2016-04-03'   1        1
'2016-04-04'   1        1
'2016-04-05'   2        1
'2016-04-06'   2        1

预期结果:

date           lastdate       state    id
'2016-04-03'   '2016-04-03'   1        1
'2016-04-04'   '2016-04-04'   1        1
'2016-04-05'   '2016-04-04'   2        1
'2016-04-06'   '2016-04-04'   2        1
'2016-04-07'   '2016-04-07'   1        1

我不完全知道我被困在哪里。感觉这个问题你看错了,所以感谢任何帮助。

提前谢谢!

编辑

似乎我没有很好地解释我的问题,这是另一个尝试:

对于每一行,我需要具有相同 id 且 state = 1 的最后一行的日期。如果 state 已经为 1,则需要同一行的日期。

所以要澄清我的“预期结果” - 表:

date           lastdate       state    id
'2016-04-03'   '2016-04-03'   1        1   

状态为 1,因此行日期是状态 1 的最后日期

'2016-04-04'   '2016-04-04'   1        1

状态为 1,因此行的日期是状态 1 的最后日期

'2016-04-05'   '2016-04-04'   2        1

状态为 2,因此日期为 1 的最后一行的日期来自前一行

'2016-04-06'   '2016-04-04'   2        1

state 为 2,state = 1 的最后日期为 '2016-04-04'

'2016-04-07'   '2016-04-07'   1        1

状态再次为 1,所以日期相同

'2016-04-08'    '2016-04-07'  2        1

state 为 2,因此设置了最后一行(前一行)的日期

我希望我的意图现在可以理解了。

【问题讨论】:

  • 请试着澄清你真正想要的东西。你对你想要什么的描述和你给出的例子似乎完全不同。
  • 尽我所能;-)
  • 好的,现在我明白你想要什么了.. 我不完全确定这只能使用 sql 但我会考虑一下

标签: mysql database postgresql select


【解决方案1】:

我会建议这样的事情(我不确定语法中的所有内容是否正确):

CREATE OR REPLACE FUNCTION dates() RETURNS TABLE (date DATE, lastdate DATE,
state INTEGER, id INTEGER) AS $$
DECLARE
   lastType1 DATE;
BEGIN
   FOR d IN (SELECT * FROM tableName)
   LOOP
       IF d.state == 1 THEN
            lastType1 = d.date;
       END IF;
       RETURN NEXT (d.date, lastType1, d.state, d.id);
   END LOOP;
   RETURN;
END
LANGUAGE 'plpgsql';

您可以通过SELECT * FROM dates() 调用它,如果您想像访问表格一样访问它,我建议您创建一个调用该函数的视图

你只需要输入你想要调用的函数而不是 dates() 而不是 tableName你的表实际上是什么

【讨论】:

    【解决方案2】:

    这是我的解决方案

    select t1.date as date, (
        select  date
            from mytable where state = 1 and t1.date::date - date::date >= 0 order by t1.date::date - date::date  limit 1
        ) as last_date
    ,t1.state , t1.id from mytable t1 where state = 2
    

    【讨论】:

    • 谢谢。也是解决问题的一种有趣方式。
    【解决方案3】:

    这可以通过加入一个表来完成:

    select distinct on (a.date) 
        a.date date, 
        coalesce(b.date, a.date) last_date, 
        a.state, 
        a.id
    from test a
    left join test b 
    on a.state = 2 and b.state = 1 and b.date < a.date
    order by a.date, b.date desc;
    
        date    | last_date  | state | id 
    ------------+------------+-------+----
     2016-04-03 | 2016-04-03 |     1 |  1
     2016-04-04 | 2016-04-04 |     1 |  1
     2016-04-05 | 2016-04-04 |     2 |  1
     2016-04-06 | 2016-04-04 |     2 |  1
     2016-04-07 | 2016-04-07 |     1 |  1
    (5 rows)
    

    【讨论】:

    • 非常感谢!我是如此接近。由于某种原因,我一直坚持内部连接的想法,因此结果是错误的。
    猜你喜欢
    • 2022-12-18
    • 1970-01-01
    • 2018-06-04
    • 2013-06-24
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-22
    相关资源
    最近更新 更多