SQL 查询理论问题 - 单语句与多语句查询

发布于 2024-08-17 04:16:38 字数 439 浏览 10 评论 0原文

当我编写 SQL 查询时,我发现自己经常想“没有办法用单个查询来做到这一点”。发生这种情况时,我经常求助于使用临时表(一种或另一种)的存储过程或多语句表值函数,最终只是简单地组合结果并返回结果表。

我想知道是否有人知道,从理论上来说,是否应该可以编写任何将单个结果集作为单个查询(而不是多个语句)返回的查询。显然,我忽略了相关的要点,例如代码可读性和可维护性,甚至可能是查询性能/效率。这更多的是关于理论 - 它可以完成......并且不用担心,当多语句在所有情况下都更适合我的目的时,我当然不打算开始强迫自己编写单语句查询,但是这可能会让我思考是否有可行的方法来从单个查询中获取结果,或者思考更长的时间。

我想有几个参数是有序的 - 我正在考虑一个关系数据库(例如 MS SQL),其表遵循常见的最佳实践(例如所有表都有主键等)。

注意:为了赢得“已接受的答案”,您需要提供明确的证据(参考网络材料或类似的东西。)

When I write SQL queries, I find myself often thinking that "there's no way to do this with a single query". When that happens I often turn to stored procedures or multi-statement table-valued functions that use temp tables (of one sort or another) and end up simply combining the results and returning the result table.

I'm wondering if anyone knows, simply as a matter of theory, whether it should be possible to write ANY query that returns a single result set as a single query (not multiple statements). Obviously, I'm ignoring relevant points such as code readability and maintainability, maybe even query performance/efficiency. This is more about theory - can it be done... and don't worry, I certainly don't plan to start forcing myself to write a single-statement query when multi-statement will better suit my purpose in all cases, but it might make me think twice or a little bit longer on whether there is a viable way to get the result from a single query.

I guess a few parameters are in order - I'm thinking of a relational database (such as MS SQL) with tables that follow common best practices (such as all tables having a primary key and so forth).

Note: in order to win 'Accepted Answer' on this, you'll need to provide a definitive proof (reference to web material or something similar.)

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

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

发布评论

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

评论(5

旧时浪漫 2024-08-24 04:16:38

我相信这是可能的。我曾经处理过非常困难的查询、非常长的查询,并且通常可以通过单个查询来完成。但大多数时候,它很难维护,所以如果您使用单个查询来完成,请确保仔细注释您的查询。

我从未遇到过无法在单个查询中完成的事情。
但有时最好在多个查询中执行此操作。

I believe it is possible. I've worked with very difficult queries, very long queries, and often, it is possible to do it with a single query. But most of the time, it's harder to mantain, so if you do it with a single query, make sure you comment your query carefully.

I've never encountered something that could not be done in a single query.
But sometimes it's best to do it in more than one query.

喜你已久 2024-08-24 04:16:38

至少在Oracle的最新版本中是绝对可以的。它有一个“模型子句”,使 sql 图灵完整。 ( http://blog.schauderhaft.de/2009/06/18/building-a-turing-engine-in-oracle-sql-using-the-model-clause/)。当然,这都是有通常的限制的,即我们实际上并没有无限的时间和内存。

对于没有这些限制的普通 sql 方言,我认为这是不可能的。

我看不到如何在“普通 sql”中实现的任务是:
一个整数类型的列

假设一个表的每一行都有
“获取当前行的值,然后返回那么多行,获取该值,返回那么多行,然后继续,直到连续两次获取相同的值并将其作为结果返回。”

At least with the a recent version of Oracle is absolutely possible. It has a 'model clause' which makes sql turing complete. ( http://blog.schauderhaft.de/2009/06/18/building-a-turing-engine-in-oracle-sql-using-the-model-clause/ ). Of course this is all with the usual limitation that we don't really have unlimited time and memory.

For a normal sql dialect without these abdominations I don't think it is possible.

A task that I can't see how to implement in 'normal sql' would be:
Assume a table with a single column of type integer

For every row
'take the value at the current row and go that many rows back, fetch that value, go that many rows back, and continue until you fetch the same value twice consecutively and return that as the result.'

[旋木] 2024-08-24 04:16:38

我无法证明这一点,但我相信答案是谨慎的“是”——前提是您的数据库设计正确。通常被迫编写多个语句来获得特定结果表明您的架构可能需要一些改进。

I can't prove it, but I believe the answer is a cautious yes - provided your database design is done properly. Usually being forced to write multiple statements to get a certain result is a sign that your schema may need some improvements.

过去的过去 2024-08-24 04:16:38

我会说“是”,但无法证明。但是,我的主要思维过程:

  • 任何选择都应该是基于集合的操作

  • 您的假设是您正在处理数学上正确的集合(即正确标准化)< /p>

  • 集合论应该保证它是可能的

其他想法:

  • 多个 SELECT 语句经常加载 temp表/表变量。这些可以在 CTE 中派生或分离。

  • 任何 RBAR 处理(无论好坏)现在都通过 CROSS/OUTER APPLY 处理到派生表

  • 我认为 UDF 在这种情况下会被归类为“作弊”,因为它允许您将 SELECT 放入另一个模块而不是在单个模块中

  • 在 DML 的“之前”序列中不允许写入:这会将状态从 SELECT 更改为 SELECT

  • 您在我们商店中看到过一些代码吗?

编辑,术语表

编辑:申请:作弊?

SELECT
    *
FROM
    MyTable1 t1
    CROSS APPLY
    (
        SELECT * FROM MyTable2 t2
        WHERE t1.something = t2.something
    ) t2

I'd say "yes" but can't prove it. However, my main thought process:

  • Any select should be a set based operation

  • Your assumption is that you are dealing with mathematically correct sets (ie normalised correctly)

  • Set theory should guarantee it's possible

Other thoughts:

  • Multiple SELECT statement often load temp tables/table variables. These can be derived or separated in CTEs.

  • Any RBAR processing (for good or bad) now be dealt with CROSS/OUTER APPLY onto derived tables

  • UDFs would be classed as "cheating" in this context I feel, because it allows you to put a SELECT into another module rather than in your single one

  • No writes allowed in your "before" sequence of DML: this changes state from SELECT to SELECT

  • Have you seen some of the code in our shop?

Edit, glossary

Edit: APPLY: cheating?

SELECT
    *
FROM
    MyTable1 t1
    CROSS APPLY
    (
        SELECT * FROM MyTable2 t2
        WHERE t1.something = t2.something
    ) t2
筑梦 2024-08-24 04:16:38

理论上是的,如果您使用函数或 OUTER APPLY 或子查询的曲折迷宫;然而,为了可读性和性能,我们最终总是使用临时表和多语句存储过程。

正如上面有人评论的那样,这通常表明您的数据结构开始出现异味;并不是说它不好,而是出于性能原因可能是时候进行非规范化了(对于我们中最好的人来说),或者可能在规范化的“真实”数据前面放置一个非规范化查询层。

In theory yes, if you use functions or a torturous maze of OUTER APPLYs or sub-queries; however, for readability and performance, we have always ended up going with temp tables and multi-statement stored procedures.

As someone above commented, this is usually a sign that your data structure is starting to smell; not that it's bad, but that maybe it's time to denormalise for performance reasons (happens to the best of us), or maybe put a denormalised querying layer in front of your normalised "real" data.

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