检查两个“select”是否相等

问题描述 投票:0回答:5

有没有办法检查两个(非平凡的)选择是否等效?

最初我希望两个选择之间有形式上的等价,但是答案在 证明 sql-query-equivalency 阻止我。

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

sql oracle select
5个回答
60
投票

如果您想比较查询结果,请尝试以下操作:

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

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


41
投票

在标准 SQL 中你可以编写以下内容

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

我想指出 MINUS 不是标准 SQL,所以我们需要使用 EXCEPT 来代替


13
投票

对于

(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
应该返回相同的列顺序,或者我们必须包装查询并确保列顺序相同。(可能会在应用程序逻辑中发生这种情况)

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

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


0
投票

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

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

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


0
投票

对我来说这成功了:

SELECT 
    BIN_TO_UUID(a.`parent_id`, true) shipmentId, 
    a.name,
    a.company
FROM shipment_address a

EXCEPT

SELECT 
    BIN_TO_UUID(s.id, true) shipmentId, 
    s.name, 
    s.company
FROM shipment s

当它们相同时我得到零结果

© www.soinside.com 2019 - 2024. All rights reserved.