检查两个“select”是否相等

发布于 2024-11-02 07:38:21 字数 221 浏览 1 评论 0原文

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

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

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

Is there a way to check if two (non-trivial) select are equivalent?

Initially I was hoping for a formally equivalence between two selects, but the answers in
proving-sql-query-equivalency stop me.

For my actual need I can just check if the (actual) results of two selects are the same.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

简美 2024-11-09 07:38:21

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

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

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

If you want to compare the query results try the following:

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

This will result in all rows that are returned by only one of the queries.

盛夏尉蓝 2024-11-09 07:38:21

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

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

我想注意的是 MINUS 不是标准 SQL,因此我们需要使用 EXCEPT 代替

In standard SQL you can write following

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

I wanted to note that MINUS is not standard SQL so we need to use EXCEPT instead

吹泡泡o 2024-11-09 07:38:21

因为

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

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

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

For

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

I did some trial on postgres 9.4, and here are my results.

[1] Minus is not supported,so need to use EXCEPT as told by @Bogdan

[2] Using only EXCEPT does not consider duplicates so had to use EXCEPT ALL

[3] EXCEPT ALL require that column order in the resultant should be same so in
above query QUERY1 and QUERY2 should either return the same column order or we have to wrap the query and make sure the column order are same.(may be this happens in application logic)

So i think if we keep above 3 points in mind we may be 100% sure that the data returned by two queries on the given data set is exactly the same.

will update if i come across more edge case which may fail.

云朵有点甜 2024-11-09 07:38:21

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

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

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

Run both of them and compare the results. Use the EXCEPT operation to subtract the set returned by the first query from the set returned by the second query. If the result is an empty set then they are equivalent.

The problem with this method is that it does not prove that two queries are equivalent for ANY database. It depends on the content of your database. For example, if your DB is empty, then any two select statements are equivalent according to this method.

Proving equivalence by just analyzing the queries is an unsolved problem AFAIK (but I'm not exactly a database theory guru, so dont trust me on that ;))
Also, you can have a look at this question: Proving SQL query equivalency

懵少女 2024-11-09 07:38:21

对我来说,这成功了:

Query_1_here

EXCEPT

Query_2_here

或者,一个更现实的例子:

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

当它们相同时,我得到零结果。请注意,两个查询中的列名称应相同。这可能会自动相同(例如,如果您在我的示例中计时 BIN_TO_UUID),则可能需要注意并需要一个简单的别名。

For me this did the trick:

Query_1_here

EXCEPT

Query_2_here

Or, a little more real world example:

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

I got zero results when they are the same. Please note that the names of the columns should be the same in both queries. This might be automatically the same (eg if you time the BIN_TO_UUID out of my example), it might be note and require a simple alias.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文