Проверить, эквивалентны ли два "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-запросов

Другие вопросы по тегам