Проверьте, эквивалентны ли два "select"
Есть ли способ проверить, эквивалентны ли два (нетривиальных) выбора?
Первоначально я надеялся на формальную эквивалентность между двумя вариантами выбора, но ответы в доказательстве sql-query-эквивалентности останавливают меня.
Для моей реальной потребности я могу просто проверить, совпадают ли (фактические) результаты двух выборов.
Ответы
Ответ 1
Если вы хотите сравнить результаты запроса, попробуйте следующее:
(select * from query1 MINUS select * from query2)
UNION ALL
(select * from query2 MINUS select * from query1)
Это приведет к тому, что все строки будут возвращены только одним из запросов.
Ответ 2
Не удалось прокомментировать ответ, заданный HAL9000, и я хотел бы отметить, что MINUS не является стандартным SQL и не работает в postgresql
Поэтому нам нужно использовать EXCEPT вместо
(select * from query1 EXCEPT select * from query2)
UNION ALL
(select * from query2 EXCEPT select * from query1)
Ответ 3
Для
(select * from query1 EXCEPT select * from query2)
UNION ALL
(select * from query2 EXCEPT select * from query1)
Я провел пробную версию на postgres 9.4
, и вот мои результаты.
[1] Минус не поддерживается, поэтому вам нужно использовать EXCEPT
, как сказано в @Bogdan
[2] Использование только EXCEPT
не рассматривает дубликаты, поэтому пришлось использовать EXCEPT ALL
[3] EXCEPT ALL
требуют, чтобы порядок столбцов в результирующем результате был таким же, как в
выше запроса QUERY1
и QUERY2
должны либо возвращать одинаковый порядок столбцов, либо мы должны обернуть запрос и убедиться, что порядок столбцов одинаковый (может быть, это происходит в логике приложения)
Поэтому я думаю, что если мы будем помнить о 3-х точках, мы можем быть на 100% уверены, что данные, возвращаемые двумя запросами в данном наборе данных, точно совпадают.
будет обновляться, если я столкнулся с более кратным случаем, который может завершиться неудачей.
Ответ 4
Запустите оба из них и сравните результаты. Используйте операцию EXCEPT для вычитания набора, возвращаемого первым запросом из набора, возвращаемого вторым запросом. Если результатом является пустое множество, то они эквивалентны.
Проблема с этим методом заключается в том, что он не доказывает, что два запроса эквивалентны для ЛЮБОЙ базы данных. Это зависит от содержимого вашей базы данных. Например, если ваша БД пуста, то любые два оператора выбора эквивалентны в соответствии с этим методом.
Доказательство эквивалентности простым анализом запросов - это нерешенная проблема AFAIK (но я не точно гуру теории базы данных, поэтому не доверяйте мне на это;))
Кроме того, вы можете посмотреть на этот вопрос: Проверка эквивалентности запросов SQL