Проверить, эквивалентны ли два "select"
Есть ли способ проверить, эквивалентны ли два (нетривиальных) выбора?
-- редактировать --
Первоначально я надеялся на формальную эквивалентность между двумя выборами, но ответы в проверке-sql-query-эквивалентности останавливают меня.
Для моей реальной потребности я могу просто проверить, совпадают ли (фактические) результаты двух выборов.
4 ответа
Если вы хотите сравнить результаты запроса, попробуйте следующее:
(select * from query1 MINUS select * from query2)
UNION ALL
(select * from query2 MINUS select * from query1)
Это приведет ко всем строкам, которые будут возвращены только одним из запросов.
Не смог прокомментировать ответ, данный HAL9000, и я хотел заметить, что MINUS не является стандартным SQL и не работает под postgresql, поэтому вместо этого нам нужно использовать EXCEPT
(select * from query1 EXCEPT select * from query2)
UNION ALL
(select * from query2 EXCEPT select * from query1)
За
(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% уверены, что данные, возвращаемые двумя запросами к данному набору данных, абсолютно одинаковы.
будет обновляться, если я столкнусь с более крайним случаем, который может не удаться.
Запустите оба из них и сравните результаты. Используйте операцию EXCEPT, чтобы вычесть набор, возвращенный первым запросом, из набора, возвращенного вторым запросом. Если результатом является пустой набор, то они эквивалентны.
Проблема этого метода в том, что он не доказывает, что два запроса эквивалентны для ЛЮБОЙ базы данных. Это зависит от содержания вашей базы данных. Например, если ваша БД пуста, то любые два оператора выбора в соответствии с этим методом эквивалентны.
Доказательство эквивалентности путем простого анализа запросов - нерешенная проблема AFAIK (но я не совсем гуру теории баз данных, поэтому не верьте мне в этом;)) Кроме того, вы можете взглянуть на этот вопрос: доказательство эквивалентности SQL-запросов