可用版本:Dev (3.21) | 最新 (3.20) | 3.19 | 3.18 | 3.17 | 3.16 | 3.15 | 3.14 | 3.13 | 3.12 | 3.11

SELECT子句的词法和逻辑顺序

适用于 ✅ 开源版   ✅ 专业版   ✅ 企业版

SQL 的 SELECT 子句具有词法顺序和逻辑顺序。SELECT 子句的词法顺序受到英语的启发。由于 SQL 语句是数据库的命令,因此用祈使语气表达语句是很自然的,例如“SELECT 这个和那个!”。

逻辑 SELECT 子句顺序

但是,SELECT 子句的逻辑顺序与语法不对应。事实上,逻辑顺序是这样的:

SQL Server 文档也解释了这一点,但子句略有不同

  • FROM
  • ON
  • JOIN
  • WHERE
  • GROUP BY
  • WITH CUBEWITH ROLLUP
  • HAVING
  • SELECT
  • DISTINCT
  • ORDER BY
  • TOP

可以看出,数据库必须在逻辑上重新排序 SQL 语句,以便确定最佳执行计划。

替代语法:LINQ, SLICK

一些“更高层”的抽象,例如 C# 的 LINQ 或 Scala 的 Slick,试图将 SELECT 子句的词法顺序反转为看起来更接近逻辑顺序的顺序。将 SELECT 子句移动到末尾的明显优势在于,SELECT 语句返回的记录类型(即投影类型)可以在内部领域特定语言的目标环境中更轻松地重用。

一个 LINQ 例子

// LINQ-to-SQL looks somewhat similar to SQL
// AS clause    // FROM clause
From p          In db.Products

// WHERE clause
Where p.UnitsInStock <= p.ReorderLevel AndAlso Not p.Discontinued

// SELECT clause
Select p

一个 Slick 例子

// "for" is the "entry-point" to the DSL
val q = for {

    // FROM clause   WHERE clause
    c <- Coffees     if c.supID === 101

// SELECT clause and projection to a tuple
} yield (c.name, c.price)

虽然这乍一看是一个好的且符合习惯的想法,但 jOOQ 的观点是,这只会使翻译为更高级的 SQL 语句变得复杂,同时会降低那些习惯于编写 SQL 的用户的可读性。对于 Slick 尤其如此,它不仅更改了 SELECT 子句的顺序,而且还大量地将 SQL 子句与 Scala 语言“集成”在一起。

jOOQ 的设计看起来就像 SQL。因此,jOOQ DSL API 按照 SQL 的词法顺序建模。

反馈

您对此页面有任何反馈吗? 我们很乐意听取您的意见!

The jOOQ Logo