Сравнение пар строк в таблице - PullRequest
2 голосов
/ 06 октября 2019

Я мог бы использовать некоторую коррективную справку для запроса, который сравнивает строки в той же таблице. Я обновляю наш код для отправки на 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;

Я хочу сохранить идентификатор, хэш, версию кодаи имя таблицы для каждой строки после каждого теста, помещаемого в небольшую таблицу:

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)
);

Вставить данные в row_check не сложно. Запрос на подтверждение концепции выглядит следующим образом:

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

И это где я в тупике. Я хотел бы создать запрос на row_check, который определяет любые идентификаторы, в которых хеш-код отличается в разных версиях. У меня есть версии 0 и 1 выше. Может ли кто-нибудь указать мне правильное направление для группировки и / или объединения, чтобы получить только строки, которые не совпадают между версиями? Это мои красные флаги, которые мне нужно обнаружить и отследить. Мне действительно нужно вернуть идентификатор и имя таблицы, версия и хеш имеют второстепенное значение. У меня есть несколько ограничений, некоторые из которых помогают:

  • Значения идентификатора уникальны для всех таблиц.

  • IЯ буду сравнивать только две версии за один раз.

  • У меня десятки таблиц для тестирования.

  • В некоторых таблицах миллионы строк.

Последний пункт может иметь значение. Я хотя бы использовал SELECT DISTINCT id в CTE, но я не продвинулся с этим.

Спасибо за совет.

1 Ответ

1 голос
/ 06 октября 2019

Если у вас есть таблица 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...