SELECT
在 ISO/IEC 标准中,SQL 为子条款规定了以下语法顺序:
SELECT
projection-expressions
FROM
sources
WHERE
predicate-expression
GROUP BY
key-expression
HAVING
predicate-expression
ORDER BY
ordering-expressions
Run Code Online (Sandbox Code Playgroud)
虽然逻辑执行顺序是这样的:
FROM
sources
WHERE
predicate-expression
GROUP BY
value-expression
HAVING
value-expression
SELECT
projection-expressions
ORDER BY
ordering-expressions
Run Code Online (Sandbox Code Playgroud)
对于 SQL 的新手用户来说,即使它是首先声明的,在SELECT
子句中定义的投影在WHERE
or子句中不可用,这变得令人惊讶GROUP BY
- 考虑到计算机程序通常遵循自上而下的执行顺序。
同样令人惊讶的是,SQL 作者需要在、 和子句中重复他们的表达式SELECT
,或者使用不适合简洁查询的子查询。至少当用户熟悉实际的子句执行顺序时,他们知道为什么需要重复自己,但这并不能阻止它令人沮丧。WHERE
GROUP BY
这个问题和其他相关问题记录在我发现的这篇文章中:https : //blog.jooq.org/a-beginners-guide-to-the-true-order-of-sql-operations/,这并不奇怪StackOverflow 上的 QA 有近 30,000 次查看:https : //stackoverflow.com/questions/3241352/using-an-alias-column-in-the-where-clause-in-postgresql
这让我想知道是否有任何 SQL 实现允许这种更“合乎逻辑”的子句排序。我注意到 .NET 中的 Linq 实际上确实遵循这个顺序,虽然我不会将它描述为真正的 SQL 实现,但实际上,在 Linq 中,等效的将是:
source // FROM equivalent
.Where( predicate-expression )
.GroupBy( key-expression )
.Where( predicate-expression ) // HAVING equivalent
.Select( projection-expression )
.OrderBy( ordering-expression )
Run Code Online (Sandbox Code Playgroud)
(我也喜欢 Linq 如何让您Select()
在命令序列中的任何位置添加投影,以便您可以使用已计算的表达式而无需再次调用表达式)。
那么,是否有任何 SQL 实现可以让您以更合乎逻辑的结构表达查询?
SQL的实现
不,SQL 是标准化的。标准的实现没有很大不同。这样就违背了目的。关于关系演算(SQL 假装是)与关系代数方法之间一直存在/一直存在争执。这是一场古老的辩论,
为数据选择了模型后,下一步是选择查询语言。关系数据库的两个高级数据子语言系列基于关系代数(源自集合代数)或关系演算 [Codd, 197lb , 1971c and Date , 1975](源自谓词演算)。Codd [1971c] 和 Date [1975] 比较了这两者,发现关系演算更优越,特别是用作自然语言系统的目标语言。他们选择关系微积分作为目标语言的主要原因是微积分是非过程性的;即,关系演算中的查询传达的关于如何继续搜索数据库的信息很少。关系代数更加程序化,这使得自然语言系统自动构建查询更加困难。——基于关系演算的查询语言的实现 1970
而且,再次来自科德本人,
在关系模型的早期(1969-1972),我发明了两种处理关系的语言:一种是代数性质的,另一种是基于一阶谓词逻辑的 [Codd 1971a]。然后我证明了这两种语言具有相同的表达能力 [Codd 1971d],但表明基于逻辑的语言将更可优化(假设没有尝试流跟踪)并且更容易用作推理软件的接口数据库管理系统。- Codd 1990,数据库管理的关系模型版本 2
这两种方法肯定有大量的实现。也就是说,SQL 作为一种实现非常固定在微积分方法上。
这些问题从未真正随着代数方法而消失,例如来自这个博客,。
context.Cars
.OrderBy(x => x.Id)
.Skip(50000)
.Take(1000)
.ToList();
Run Code Online (Sandbox Code Playgroud)
需要手动优化,因为,
context.Cars
.Where(x => context.Cars
.OrderBy(y => y.Id)
.Select(y => y.Id)
.Skip(50000)
.Take(1000)
.Contains(x.Id)
)
.ToList();
Run Code Online (Sandbox Code Playgroud)
如果您有多个具有不同性能特征(索引,其中大部分被实现为间接和抽象)和统计数据的不同关系,则很难编写有效工作的过程集逻辑。
归档时间: |
|
查看次数: |
522 次 |
最近记录: |