【问题标题】:Select pair of rows values by specific rule for other columns按特定规则为其他列选择一对行值
【发布时间】:2019-06-05 20:14:23
【问题描述】:

试图了解我该怎么做:


|id|         timestamp        |   type  |
|--|--------------------------|---------|
|11|2018-10-02 15:57:07.000000|  open   |
|11|2018-10-02 16:48:51.000000|  closed |
|11|2018-10-05 08:59:27.000000|  open   |
|11|2018-10-05 09:59:18.000000|  closed |

那个:

|id|          open_ts         |         closed_ts        |
|--|--------------------------|--------------------------|
|11|2018-10-02 15:57:07.000000|2018-10-02 16:48:51.000000|
|11|2018-10-05 08:59:27.000000|2018-10-05 09:59:18.000000|

我根据类型的条件进行了“自联接”。 这里有一个规则:在“打开”之后应该总是“关闭”。在“关闭”之前,它不能“打开”。 我最好的结果是:

|id|          open_ts         |         closed_ts        |
|--|--------------------------|--------------------------|
|11|2018-10-02 15:57:07.000000|2018-10-02 16:48:51.000000|
|11|2018-10-02 15:57:07.000000|2018-10-05 09:59:18.000000|
|11|2018-10-05 08:59:27.000000|2018-10-02 16:48:51.000000|
|11|2018-10-05 08:59:27.000000|2018-10-05 09:59:18.000000|

select z.id id, z.timestamp open_ts, o.timestamp closed_ts
from temp_event z
       join temp_event o
         on z.id=o.id
where z.type='open' and o.type='closed'

另外,我尝试在 (id)* 上使用 distinct,但我得到了错误的间隔值:

|id|          open_ts         |         closed_ts        |
|--|--------------------------|--------------------------|
|11|2018-10-02 15:57:07.000000|2018-10-02 16:48:51.000000|
|11|2018-10-05 08:59:27.000000|2018-10-02 16:48:51.000000|

* 来自附加表。此 id 存在于两个副本中,用于呈现表中的一个 id。

【问题讨论】:

    标签: sql postgresql join timestamp


    【解决方案1】:

    使用窗口函数row_number() 指定对:

    with temp_rn as (
        select *, row_number() over (partition by id, type order by timestamp) as rn
        from temp_event
    )
    select t1.id, t1.timestamp as open_ts, t2.timestamp as close_ts
    from temp_rn t1
    join temp_rn t2 
    on t1.id = t2.id and t1.rn = t2.rn and t1.type > t2.type
    
     id |       open_ts       |      close_ts       
    ----+---------------------+---------------------
     11 | 2018-10-02 15:57:07 | 2018-10-02 16:48:51
     11 | 2018-10-05 08:59:27 | 2018-10-05 09:59:18
    (2 rows)    
    

    【讨论】:

      【解决方案2】:

      你可以使用lead():

      select  id, timestamp as open_ts, closed_ts
      from (select t.*,
                   lead(timestamp) filter (where type = 'closed') over (partition by id order by timestamp) as closed_ts
            from t
           ) t
      where type = 'open';
      

      【讨论】:

      • 我使用的是 postgres 10.6。我不知道如何使用'lead'和许多其他东西,但我的控制台说'filter where'附近有语法错误:(
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-03
      • 2016-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多