简体   繁体   English

如何从不同的表中查询两列序列之间的差异

[英]How to query for the difference between the sequences of two columns, from differing tables

I need a query that will compare the sequences of two columns (from two different tables) and display the first differing result.我需要一个查询来比较两列的序列(来自两个不同的表)并显示第一个不同的结果。 Summary with details follow:详细摘要如下:

  • Operating out of a PostgreSQL server and using DBeaver在 PostgreSQL 服务器上运行并使用 DBeaver
  • Two tables with identical column headers.具有相同列标题的两个表。
  • One entry (creq_id) will have 36 sequences (seq).一个条目 (creq_id) 将有 36 个序列 (seq)。
  • When the UI modifies the data (chan_id), Table B records the new entry.当 UI 修改数据 (chan_id) 时,表 B 记录新条目。
    • Modification can be a change to original value or a new addition to the sequence.修改可以是对原始值的更改或对序列的新添加。
  • Query should compare each sequence (total of 36 sequences) from both tables and stop at the first difference which is recorded in Table B.查询应该比较两个表中的每个序列(总共 36 个序列),并在表 B 中记录的第一个差异处停止。

Example of changing/overwriting a chan_id:更改/覆盖 chan_id 的示例:

Table A表 A

creq_id creq_id chan_id chan_id seq序列
29022 29022 400 400 1 1
29022 29022 0 0 2 2
29022 29022 0 0 3 3

Table B表 B

creq_id creq_id chan_id chan_id seq序列
29022 29022 500 500 1 1
29022 29022 0 0 2 2
29022 29022 0 0 3 3

Example of adding a new chan_id添加新 chan_id 的示例

Table A表 A

creq_id creq_id chan_id chan_id seq序列
29022 29022 400 400 1 1
29022 29022 0 0 2 2
29022 29022 0 0 3 3

Table B表 B

creq_id creq_id chan_id chan_id seq序列
29022 29022 400 400 1 1
29022 29022 500 500 2 2
29022 29022 0 0 3 3

In either case above, the result I am seeking:在上述任何一种情况下,我正在寻求的结果:

  • Table A.chan_id as orig_value表 A.chan_id 作为 orig_value
  • Table B.chan_id as new_value表 B.chan_id 作为 new_value
orig_value原始值 new_value新值
400 400 500 500

The basic query is to join each table by creq_id and seq_id, then check if their chan_ids are not equal.基本查询是通过creq_id和seq_id连接每个表,然后检查它们的chan_ids是否不相等。

To differentiate between a change and an add, if tableA's chan_id is 0 then it's a change and we need to use chan_id from the previous sequence.为了区分更改和添加,如果 tableA 的 chan_id 为 0,那么它是更改,我们需要使用前一个序列中的 chan_id。 We get that with a subquery.我们通过子查询得到它。

select
  a.creq_id,
  case a.chan_id
  when 0 then (
      -- Get the previous chan_id
      select chan_id
      from tablea
      where creq_id = a.creq_id
        and seq = a.seq - 1
  )
  else
      a.chan_id
  end as original,
  b.chan_id as new,
  a.seq,
  b.seq
from tablea a
join tableb b on a.creq_id = b.creq_id and a.seq = b.seq
where a.chan_id != b.chan_id

This causes a problem, what if you want to store a 0 then change it?这会导致一个问题,如果你想存储一个 0 然后改变它呢? It looks the same as having added a new value.它看起来与添加新值相同。 To avoid this, use null instead of 0 to mean "no value".为避免这种情况,请使用null而不是 0 来表示“无价值”。

select
  a.creq_id,
  coalesce(
      a.chan_id,
      (
        -- Get the previous chan_id
        select chan_id
        from tablea
        where creq_id = a.creq_id
          and seq = a.seq - 1
      )
  ) as original,
  b.chan_id as new,
  a.seq,
  b.seq
from tablea a
join tableb b on a.creq_id = b.creq_id and a.seq = b.seq
-- skip when both columns are null, because null != null
where (a.chan_id is null and b.chan_id is not null)
   or a.chan_id != b.chan_id

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM