2010-01-06 121 views
6

当我编写SQL查询时,我发现自己经常会认为“没有办法用单个查询来做到这一点”。当发生这种情况时,我经常转向存储过程或使用临时表(多种语言)的多语句表值函数,最后只需将结果合并并返回结果表即可。SQL查询理论问题 - 单一语句与多语句查询

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

我想几个参数是为了 - 我正在考虑关系数据库(如MS SQL)与表遵循常见的最佳做法(如所有表具有主键等)。

注:(参考材料纤维网或类似的东西),以赢得“接受的答案”这一点,你需要提供明确的证据

+0

...或反例。 – 2010-01-06 19:16:19

+0

在您回答这个问题之前,您需要对“SQL理论”中的含义有更多的具体说明。实践中使用的SQL在DBMS和DBMS版本之间有所不同。您需要标准化一组标准的SQL结构。例如,你允许什么类型的子查询?此外,您可能希望抽象出一些细节,例如最常用的“SQL查询理论”,它使用关系演算或代数作为SQL的抽象,将表格视为行集,而不是有序的行列表。 – reinierpost 2011-04-29 13:38:56

回答

2

至少在最近的一个版本的Oracle中是绝对有可能的。它有一个使模型完整的“模型条款”。 (http://blog.schauderhaft.de/2009/06/18/building-a-turing-engine-in-oracle-sql-using-the-model-clause/)。当然,这都与通常的限制有关,我们并没有无限的时间和记忆。

对于一个正常的sql方言没有这些abdominations我不认为这是可能的。

,我不能看到如何在“正常SQL”将实现一个任务: 假设一个表型整数

的单个列的每一行 “取值在当前行并返回多行,获取该值,返回多行,然后继续,直到连续两次获取相同的值,并将结果作为结果返回。

+0

哇非常有趣...但是在我看来(如果我理解正确的话),虽然这是一个单独的声明,但它并不完全符合我的问题的精神,因为您有能力迭代结果表。我想我正在更多地沿着“集合论”的思路思考。尽管如此,这实现了Turing-complete状态,并且提到了大多数SQL(我认为这意味着MSSQL)“可能不是”足以胜出,我想,即使我'米仍然不确定我的“真正”问题的最终答案是什么。 – 2010-01-06 22:38:58

3

我相信这是可能的。我已经处理了非常困难的查询,非常长的查询,并且通常可以通过单个查询来完成。但大多数情况下,更难以维护,所以如果您只使用一个查询来完成,请确保您仔细评论您的查询。

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

+0

要添加一些信息:在我的工作中,我们有备份超过60的数据库。我们使用非常大的表格和非常大的数据。 对于我们所做的工作类型,查询可以执行多个页面,因此通常最好执行多个查询或使用工作表。 – 2010-01-06 18:46:51

+0

“querie做了很多页面”是什么意思? – 2010-01-06 18:59:44

+0

我的意思是说,当你把它写在你的程序中(我用C++工作)时,你必须在查询结束之前向下滚动很多页面。 – 2010-01-07 16:45:37

2

我无法证明它,但我相信答案是谨慎的 - 只要你的数据库设计正确完成。通常被迫编写多个语句以获得特定结果表明您的模式可能需要一些改进。

2

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

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

  • 你的假设是,你是在处理数学上正确设置(即正确标准化)

  • 集合论应保证其有可能

其他的想法:

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

  • 任何RBAR处理(好或坏)现在可以处理CROSS/OUTER应用到派生表

  • 的UDF会被归类为在这方面,我觉得“欺骗”,因为它可以让你把a。选择到另一个模块,而不是在你的单身一个

  • 任何写在你的DML序列“之前”允许:这改变了从选择状态来选择

  • 你有没有在我们的商店看到一些代码?

编辑,词汇

编辑:适用于:作弊?

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

什么是rbar,cte和udf? – 2010-01-06 18:53:56

+0

我刚刚阅读了'申请',这听起来对我来说也是一种欺骗。它调用一个函数,它不是一个真正的SQL实体,而是在T-SQL中实现的,或者它所调用的任何函数。 – 2010-01-06 19:11:11

1

理论上是的,如果你使用外部应用程序或子查询的函数或曲折的迷宫;然而,为了可读性和性能,我们总是以临时表和多语句存储过程结束。

上面有人评论道,这通常表明您的数据结构开始闻起来了;不是不好,,但是也许是出于性能原因(发生在我们身上)发生非规范化的时候,或者可能在规范化的“真实”数据前面放置一个非规范化查询层。