Проверьте, эквивалентны ли два "select" - PullRequest
21 голосов
/ 20 апреля 2011

Есть ли способ проверить, эквивалентны ли два (нетривиальных) выбора?

Изначально я надеялся на формальную эквивалентность между двумя выборами, но ответы в proving-sql-query-эквивалентность останови меня.

Для моей реальной потребности я могу просто проверить, совпадают ли (фактические) результаты двух выборов.

Ответы [ 4 ]

32 голосов
/ 20 апреля 2011

Если вы хотите сравнить результаты запроса, попробуйте следующее:

(select * from query1 MINUS select * from query2) 
UNION ALL
(select * from query2 MINUS select * from query1)

Это приведет к тому, что все строки будут возвращены только одним из запросов.

10 голосов
/ 20 марта 2015

Не удалось прокомментировать ответ, данный HAL9000, и я хотел отметить, что МИНУС не является стандартным SQL и не работает под postgresql Таким образом, мы должны использовать EXCEPT вместо

(select * from query1 EXCEPT select * from query2) 
UNION ALL
(select * from query2 EXCEPT select * from query1)
2 голосов
/ 26 декабря 2015

Для

(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% уверены, что данные, возвращаемые двумя запросами к данному набору данных, абсолютно одинаковы.

будет обновляться, если я столкнусь с более сложным случаем, который может дать сбой.

0 голосов
/ 20 апреля 2011

Запустите их оба и сравните результаты. Используйте операцию EXCEPT, чтобы вычесть набор, возвращаемый первым запросом, из набора, возвращенного вторым запросом. Если результатом является пустой набор, то они эквивалентны.

Проблема этого метода в том, что он не доказывает, что два запроса эквивалентны для ЛЮБОЙ базы данных. Это зависит от содержимого вашей базы данных. Например, если ваша БД пуста, то любые два оператора выбора в соответствии с этим методом эквивалентны.

Доказательство эквивалентности путем простого анализа запросов - нерешенная проблема AFAIK (но я не совсем гуру теории баз данных, поэтому не верьте мне в этом;)) Также вы можете взглянуть на этот вопрос: Подтверждение эквивалентности SQL-запросов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...