对于比较同一表中的行的查询,我可以使用一些补救帮助。我正在修改推送Postgres的代码,并设置了一个测试台来使用新旧代码推送。行计数很好,但这不能告诉我数据是否相同。为此,我意识到我可以使用内置功能来获取行的散列。下面是我的一张简单的表格:

CREATE TABLE IF NOT EXISTS data.hsys (
    "id" uuid NOT NULL DEFAULT NULL,
    "marked_for_deletion" boolean NOT NULL DEFAULT false,
    "name_" citext NOT NULL DEFAULT NULL,

CONSTRAINT hsys_id_pkey
    PRIMARY KEY ("id")
);

然后散列只取这一行:
select hashtext(hsys::text) from hsys;

我要做的是将每一行的ID、hash、代码版本和表名存储在一个小表中:
CREATE TABLE IF NOT EXISTS data.row_check (
    id         uuid NOT NULL DEFAULT NULL,
    version    int8 NOT NULL DEFAULT NULL,
    row_hash   int8 NOT NULL DEFAULT NULL,
    table_name text NOT NULL DEFAULT NULL,

CONSTRAINT row_check_pkey
    PRIMARY KEY (id, version)
);

将数据插入行检查并不困难。概念证明查询如下所示:
select
   id,
    0 as version,
    hashtext(hsys::text)  as row_hash,
   'hsys' as table_name,
from hsys;

正在工作的插入查询如下所示:
INSERT INTO row_check (id,version,row_hash,table_name)
            SELECT id, 0, hashtext(hsys::text),'hsys'
            FROM hsys

            ON CONFLICT ON CONSTRAINT row_check_pkey DO UPDATE SET
                row_hash   = EXCLUDED.row_hash,
                table_name = EXCLUDED.table_name;

一旦数据到位,我就可以这样看:
select * from row_check
order by 1,2
limit 6;

id                                    version   row_hash    table_name
17ea1ed4-87b0-0840-912f-d29de2a06f5d    0      -1853961325  hsys
17ea1ed4-87b0-0840-912f-d29de2a06f5d    1      -1853961325  hsys
2200d1da-73e7-419c-9e4c-efe020834e6f    0      -482794730   hsys
2200d1da-73e7-419c-9e4c-efe020834e6f    1       482794730   hsys   <--- Different from version 0
47f4a50e-2358-434b-b30d-1f707ea9ee1b    0      -1539190835  hsys
47f4a50e-2358-434b-b30d-1f707ea9ee1b    1      -1539190835  hsys

理想情况下,我希望从这样的样本中:
table_name id                                       v0         v1
hsys       2200d1da-73e7-419c-9e4c-efe020834e6f 0   -482794730  482794730

但即使是这个最小的结果也会有帮助:
2200d1da-73e7-419c-9e4c-efe020834e6f    hsys

我就在这里被难住了。我想构建的是一个行检查查询,它可以在不同版本之间的散列不同的地方找到任何id。我有0和1以上的版本。有人能给我指一个正确的方向来分组和/或连接,以便只得到在不同版本中不匹配的行吗?这些是我的红旗,我需要找出并追踪。我真的需要回ID和表名,版本和散列是次要的。我有一些限制,其中一些有助于:
ID值在所有表中都是唯一的。
我一次只比较两个版本。
我有几十张桌子要测试。
有些表有数百万行。
最后一点可能很重要。我想在CTE中使用SELECT DISTINCT id,但我没有做太多。
谢谢你的建议。

最佳答案

一旦有了row_check表,就可以这样加入表

 select a.id
      , a.version
      , a.row_hash
      , b.id
      , b.version
      , b.row_hash
from row_check a
INNER JOIN row_check b on a.id = b.id
  AND a.version = 0
    AND b.version  = 1
      AND a.row_hash <> b.row_hash

关于postgresql - 比较表中的行对,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58254541/

10-13 00:32
查看更多