【问题标题】:Detecting the change on the certain column in the history table检测历史表中某列的变化
【发布时间】:2017-08-15 06:37:24
【问题描述】:

考虑以下数据:

history.data
=======================================
id |data_id| col1  | col2  | date
---+-------+-------+-------+-----------
1  |1      | 123   | 321   | 2017-08-01
2  |1      | 124   | 321   | 2017-08-03
3  |2      | 222   | 555   | 2017-08-05
4  |2      | 242   | 555   | 2017-08-07
5  |2      | 242   | 333   | 2017-08-11

所以这是history_data 表,我将所有更改保存在某个表中。 现在我需要在col1 列中获取data 的每个当前条目的最后更改日期。 在这种情况下,所需的输出应该是

data_id | date
--------+-----------
1       | 2017-08-03
2       | 2017-08-07

我需要在以下情况下这样做:

with cte1 as (
    select distinct on(data_id)
    data_id,
    date::date

    from data d
    join history.data hd on hd.data_id = d.id
    order by d.id, hd.date desc
)

如您所见,现在我只获取上次记录更改的日期,而不管更改发生在哪一列。

谁能帮帮我?

【问题讨论】:

  • 为什么 data_id=2 你期望日期 2017-08-07 而不是 2017-08-11
  • @OtoShavadze 因为在2017-08-11 上发生了更改,在col2 上发生了变化,但我只对col1 上的更改感兴趣。

标签: sql postgresql postgresql-9.4


【解决方案1】:

您可以使用lag() 获取先前的prev_col1 值,并使用prev_col1 <> col1 来识别发生更改的所有行:

select distinct on(data_id) * from (
    select lag(col1) over (partition by data_id order by d.id) prev_col1,
    d.id,
    col1,
    data_id,
    date::date
    from data d
    join history.data hd on hd.data_id = d.id
) t where prev_col1 <> col1 or prev_col1 is null
order by id desc

prev_col1 is null 条件对于每个 data_id 仅有 1 个成员的组是必需的,并假定第一个成员符合更改条件。

【讨论】:

    【解决方案2】:
    select data_id, max(mindt) from (
        select data_id, col1, min(date) as mindt
        from history_data
        group by data_id, col1
    ) t
    group by data_id
    

    【讨论】:

      【解决方案3】:

      您可以使用以下查询:

      select distinct on(data_id)
             data_id,
             col1
      from data d
      join history_data hd on d.id = hd.data_id
      order by data_id, date desc;
      

      获取每个data_id最后一个 col1 值:

      data_id col1
      -------------
      1   124
      2   242
      

      将上述查询用作派生表,您可以连接回原始表以获取每个组的最早日期:

      select t1.data_id, t1.col1, min(date::date)
      from history_data t1
      join (
         select distinct on(data_id)
                data_id,
                col1
         from data d
         join history_data hd on d.id = hd.data_id
         order by data_id, date desc
      ) t2 on t1.data_id = t2.data_id and t1.col1 = t2.col1
      group by t1.data_id, t1.col1;
      

      输出:

      data_id col1    min
      ---------------------------
      1       124     03.08.2017 
      2       242     07.08.2017 
      

      注意:该查询还将返回与一个 col1 值相关的data_id 组。您需要稍微更改查询以过滤掉这些行,以防您不需要它们。

      Demo here

      【讨论】:

        猜你喜欢
        • 2021-11-29
        • 1970-01-01
        • 2021-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-14
        • 1970-01-01
        相关资源
        最近更新 更多