Postgresql 比较表中的行对

Postgresql 比较表中的行对,postgresql,testing,grouping,Postgresql,Testing,Grouping,对于比较同一表中的行的查询,我可以使用一些补救帮助。我正在修改我们的代码,以便推送到博士后,并建立了一个测试平台,使用我们的新旧代码推送。行计数很好,但这不能告诉我数据是否相同。为此,我意识到我可以使用内置特性来获取行的散列。以下是我的一个简单表格作为开始: CREATE TABLE IF NOT EXISTS data.hsys ( "id" uuid NOT NULL DEFAULT NULL, "marked_for_deletion" boolean NOT NULL D

对于比较同一表中的行的查询,我可以使用一些补救帮助。我正在修改我们的代码,以便推送到博士后,并建立了一个测试平台,使用我们的新旧代码推送。行计数很好,但这不能告诉我数据是否相同。为此,我意识到我可以使用内置特性来获取行的散列。以下是我的一个简单表格作为开始:

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、哈希、代码版本和表名存储到一个小表中:

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
工作插入查询如下所示:

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
一旦数据到位,我就可以这样看:

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
但即使是这个最小的结果也会有帮助:

2200d1da-73e7-419c-9e4c-efe020834e6f    hsys
这就是我被难倒的地方。我想要构建的是一个关于行检查的查询,它可以发现任何不同版本之间散列不同的ID。我有0和1以上的版本。有人能告诉我分组和/或连接的正确方向,以便只获得不同版本之间不匹配的行吗?这些是我需要发现和追踪的危险信号。我真的需要返回ID和表名,版本和哈希是次要的。我在这方面有一些限制,其中一些有助于:

  • ID值在所有表中都是唯一的

  • 我一次只比较两个版本

  • 我有几十张桌子要测试

  • 有些表有数百万行

最后一点可能很重要。我曾想过在CTE中使用
SELECT DISTINCT id
,但我没有做到这一点


谢谢你的建议。

一旦你有了行检查表,你就可以这样加入表了

 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
选择一个id
,a.版本
,a.row\u hash
,b.id
,b.版本
,b.row_hash
从a行开始检查
a.id=b.id上的内部联接行检查b
和a.version=0
和b.version=1
和a.row\u hash b.row\u hash

这节省了我很多时间。