Sql 检测历史记录表中特定列的更改

Sql 检测历史记录表中特定列的更改,sql,postgresql,postgresql-9.4,Sql,Postgresql,Postgresql 9.4,考虑以下数据: 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-0

考虑以下数据:

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
这是一个历史数据表,我把所有的变化都保存在一个表中。 现在,我需要为col1列中的每个当前数据条目获取上次更改的日期。 在这种情况下,所需的输出应为

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
)
正如你所看到的,现在我只是得到最后一次记录更改的日期,不管更改发生在哪一列

有人可以帮我吗?

您可以使用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

对于每个数据id只有1个成员的组,需要prev_col1 is null条件,并假定第一个成员符合更改条件。

您可以使用以下查询:

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
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;
要获取每个数据\u id的最后一个col1值,请执行以下操作:

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

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;
输出:

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

为什么数据_id=2的日期是2017-08-07而不是2017-08-11?@OtoShavadze,因为2017-08-11的变更发生在col2上,但我只对col1上的变更感兴趣。
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