检查两个“选择”是不是相等
Posted
技术标签:
【中文标题】检查两个“选择”是不是相等【英文标题】:Check if two "select"s are equivalent检查两个“选择”是否相等 【发布时间】:2011-08-09 07:56:46 【问题描述】:有没有办法检查两个(非平凡的)选择是否等价?
最初我希望两个选择之间有形式上的等价性,但答案在 proving-sql-query-equivalency阻止我。
对于我的实际需要,我可以检查两个选择的(实际)结果是否相同。
【问题讨论】:
您想比较两个 SELECT 字符串吗?还是结果?请提供更多信息。 '检查两个“select”是否相等”,在Query中哪里检查?存储过程?查看?请描述一下。 Proving SQL query equivalency的可能重复 【参考方案1】:如果您想比较查询结果,请尝试以下操作:
(select * from query1 MINUS select * from query2)
UNION ALL
(select * from query2 MINUS select * from query1)
这将导致仅由其中一个查询返回的所有行。
【讨论】:
如果出现零行,但这并不意味着查询在语义上是等效的。这只是意味着使用当前的数据集,它们会给出相同的结果。不过,这对于原始海报来说可能已经足够了,但我认为值得指出。 @Rob van Wijk 你是对的,但是选择工作的表几乎没有(和受控)修改,所以我可以“切实”地相信新选择是一个有效的“插入” "旧的 这并不能确保以相同的顺序返回行。【参考方案2】:在标准 SQL 中,您可以编写以下代码
(select * from query1 EXCEPT select * from query2)
UNION ALL
(select * from query2 EXCEPT select * from query1)
我想指出,MINUS 不是标准 SQL,所以我们需要改用 EXCEPT
【讨论】:
【参考方案3】:对于
(select * from query1 EXCEPT select * from query2)
UNION ALL
(select * from query2 EXCEPT select * from query1)
我在postgres 9.4
上做了一些试验,这是我的结果。
[1] 不支持减号,所以需要使用@Bogdan 所说的EXCEPT
[2] 仅使用 EXCEPT
不考虑重复,因此必须使用 EXCEPT ALL
[3] EXCEPT ALL
要求结果中的列顺序应该相同
以上查询 QUERY1
和 QUERY2
应该返回相同的列顺序,或者我们必须包装查询并确保列顺序相同。(可能发生在应用程序逻辑中)
所以我认为,如果我们牢记 3 点以上,我们可能 100% 确定给定数据集上的两个查询返回的数据完全相同。
如果我遇到更多可能失败的边缘情况,将更新。
【讨论】:
【参考方案4】:同时运行它们并比较结果。使用 EXCEPT 操作从第二个查询返回的集合中减去第一个查询返回的集合。如果结果是一个空集,那么它们是等价的。
这种方法的问题在于它不能证明两个查询对于任何数据库都是等价的。这取决于您的数据库的内容。例如,如果您的数据库为空,则根据此方法,任何两个 select 语句都是等效的。
仅通过分析查询来证明等效性是一个未解决的问题 AFAIK(但我不完全是数据库理论专家,所以不要相信我;)) 另外,你可以看看这个问题:Proving SQL query equivalency
【讨论】:
"如果结果是一个空集,那么它们是等价的。" -- 不一定,如果第二个查询返回第一个的所有记录加上其他记录,那么您仍然会得到一个空集(EXCEPT
不可交换)。以上是关于检查两个“选择”是不是相等的主要内容,如果未能解决你的问题,请参考以下文章