2011-04-20 169 views
17

有没有办法检查两个(非平凡)select是否相等?检查两个“select”是否相等

- 编辑 -

起初我希望的两个选择之间的正式等价,但在 proving-sql-query-equivalency答案阻止我。

对于我的实际需要,我可以检查两个选择的(实际)结果是否相同。

+2

你想比较两个SELECT字符串吗?或结果?请提供更多信息。 – wegginho 2011-04-20 09:04:15

+0

'检查两个“选择”是否相等“,在Query?存储过程?查看中检查它的位置?请描述一下。 – 2011-04-20 09:05:04

+0

[证明SQL查询等同性]的可能重复(http://stackoverflow.com/questions/56895/proving-sql-query-equivalency) – 2011-04-20 09:42:59

回答

26

如果要比较的查询结果尝试以下操作:

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

这将导致由只的一个查询返回的所有行。

+12

如果出现零行,但这并不意味着查询语义上相同。这只是说,使用当前的数据集,他们会得到相同的结果。虽然这可能对原始海报足够好,但我认为值得指出。 – 2011-04-20 09:18:35

+0

@Rob van Wijk你是对的,但是选择作品的表格只有很少(和受控制的)修改,所以我可以对新选择作为一个有效的“下降” – 2011-04-20 10:25:16

0

运行它们并比较结果。使用EXCEPT操作减去由第二个查询返回的集合中第一个查询返回的集合。如果结果是空集,那么它们是等价的。

这种方法的问题在于,它不能证明两个查询对于任何数据库都是等价的。这取决于你的数据库的内容。例如,如果您的数据库为空,则根据此方法,任何两个选择语句都是等效的。

通过分析查询证明等价是一个未解决的问题AFAIK(但我不完全是数据库理论大师,所以不要相信我) 此外,你可以看看这个问题:Proving SQL query equivalency

+1

“如果结果是空集,那么它们是等效的。” - 不一定,如果第二个查询返回第一个加上附加记录的所有记录,那么你仍然会得到一个空集('''EXCEPT'''不可交换)。 – 2014-07-04 17:56:43

3

无法通过HAL9000给出的答案进行评论,我想指出,减号是不是标准的SQL,并没有在PostgreSQL的 工作,所以我们需要EXCEPT代替

(select * from query1 EXCEPT select * from query2) 
UNION ALL 
(select * from query2 EXCEPT select * from query1) 
1

使用

(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要求在结果中的列顺序应该是相同的,因此在查询QUERY1QUERY2之上的 应该返回相同的列顺序,或者我们必须包装查询并确保列顺序相同(可能发生在应用程序逻辑中)

所以我认为如果我们记住3点以上,我们可能会100%确定在给定数据集上的两个查询返回的数据是完全相同的。

将更新,如果我遇到更多的边缘情况下可能会失败。