【问题标题】:Why can identifiers in SQL be referenced before assignment?为什么 SQL 中的标识符可以在赋值前被引用?
【发布时间】:2020-11-05 21:53:59
【问题描述】:

在 SQL 查询中,您可以在声明名称之前引用该名称。

SELECT A.id FROM table_a A;

这种行为的历史是什么?它与需要您在引用变量之前分配给变量的编程语言有何关系?

【问题讨论】:

  • 这些都不是“变量”。变量将是declare @id int。在 TSql 中,您也不能在声明变量之前引用它,因此任何其他编程语言都没有变化。
  • 传统。而且评估顺序有点不直观。
  • @igor 什么是正确的术语而不是变量。这里的“A”是什么?
  • A 是引用 table_a 的别名,它恰好是一个表。

标签: sql language-design


【解决方案1】:

您误解了 SQL 语言的性质。它不是一种程序语言,而是一种声明性语言。该语句描述了结果应该是什么样子,并且数据库会相应地构建实际的查询计划 - 默认情况下,您看不到。

一些数据库提供了某种程序子语言,可以用来编写程序——例如Oracle中的PL/SQL。但是,您在此处显示的是标准 SQL SELECT 语句。那里没有变量声明的概念。 FROM 子句中的Atable_a 的别名,也就是标识符,您可以使用<table identifier>.<column name> 之类的表达式来引用表的列。

【讨论】:

  • 一个有助于理解的细微差别,这是分阶段完成的吗?在创建查询计划之前是否有别名解析/解析阶段?
  • @IanDanforth:您无需担心数据库如何进行查询(除非您正在进行一些高级优化)。您只需要专注于如何编写有效的 SQL,正确描述您想要的结果。
【解决方案2】:

为什么SQL中的标识符可以在赋值前被引用?

它是表的别名。但这里的重点是SQL不应该自顶向下阅读。

SELECT A.id 
FROM table_a A;

实际上执行起来更像:

FROM table_a A
SELECT A.id;

现在它很有意义。


更进一步:

SELECT A.id + 1 AS c 
FROM table_a A
WHERE c = 10;
-- error, we cannot use c, even if it was defined 2 lines before

因为顺序如下:

FROM table_a A
WHERE c = 10       -- here C is not defined
SELECT A.id + 1 c;

即使在SELECT 的同一级别上,也无法重用已定义的别名:

 SELECT a + 1 AS b, b + 1 AS c, c + 1 AS d
 FROM tab
 -- error
 -- (some databases allow to use lateral column aliasing)

相关阅读:

Why do “linq to sql” queries starts with the FROM keyword unlike regular SQL queries?

Lexical and logical SELECT clause order

All-at-once rule

【讨论】:

    猜你喜欢
    • 2021-04-16
    • 1970-01-01
    • 2021-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多