Проверить, возвращают ли два оператора select один и тот же результат в заданном наборе данных
(select * from query1 EXCEPT select * from query2)
UNION ALL
(select * from query2 EXCEPT select * from query1)
Я наткнулся на запрос выше, чтобы решить эту проблему. Я провел несколько испытаний на Postgres 9.4, и вот мои результаты.
1 минус не поддерживается, поэтому нужно использовать EXCEPT
[2] Использование только EXCEPT не учитывает дубликаты, поэтому пришлось использовать EXCEPT ALL
[3] ЗА ИСКЛЮЧЕНИЕМ ВСЕГО требуется, чтобы порядок столбцов в результирующем файле был таким же, как и в приведенном выше запросе. QUERY1
а также QUERY2
должен либо вернуть тот же порядок столбцов, либо нам нужно обернуть запрос и убедиться, что порядок столбцов одинаков (возможно, это происходит в логике приложения)
Так что, если мы будем иметь в виду выше трех пунктов, мы будем на 100% уверены в нашем результате, верно?
ПРИМЕЧАНИЕ: я также упомянул выше 3 пункта в ответе на вопрос. Я спросил это здесь, чтобы я мог быть уверен,
1 ответ
Нет, вы все еще не гарантированы, как вы можете легко увидеть из этого примера:
select *
from (select 1 as x union all select 1) x
except
select 1;
Это возвращает 0 строк, даже если два запроса не совпадают.
Проблема в дубликатах.
Один из методов - преобразовать все значения в строке в общее значение. Postgres имеет интересный синтаксис для этого:
select table_alias::text
from (. . . ) table_alias
Это объединяет все значения вместе. Затем вы можете использовать это в row_number()
выражение. Вы можете подключить это в except
выражение у вас есть. Добавление row_number()
исправит проблему с дубликатами. Использование:
row_number() over (order by q1::text)
будет гарантировать, что идентичные строки находятся в одинаковом порядке.