我偶然发现了 sqlite 的查询数独查询https://www.sqlite.org/lang_with.html
,并注意到它们使用以下语法:
[other stuff...]
SELECT 1
FROM digits AS lp
WHERE z.z = substr(s, ((ind-1)/9)*9 + lp, 1)
[...more stuff]
其中digits
是之前定义的临时表:digits(z text, lp int)
。但是,该表达式((ind-1/9)*9 + lp
显然是有效的语法,但我认为不可能直接在表上添加?
在这里,我做了一个可重现的示例(使用 postgres)来说明什么有效,什么无效:
-- fails: no table alias
with digits(d, s) as (values (1, '1'))
select * from digits where digits >= 1;
-- works: alias to d
with digits(d, s) as (values (1, '1'))
select * from digits as d where d >= 1;
-- fails: alias to foo
with digits(d, s) as (values (1, '1'))
select * from digits as foo where foo >= 1;
-- works: alias to foo, but treat as a record
with digits(d, s) as (values (1, '1'))
select * from digits as foo where foo.d >= 1;
这里发生了什么?我在哪里可以阅读更多相关内容?它似乎是sql标准的一部分?
列名优先于表名。当范围内没有匹配列时,非限定标识符(“简单名称”)只能解析为范围内表表达式的行类型。在您给定的示例中,有一列,就像您的示例中
digits.lp
有一列一样。digits.d
一切都如预期。手册:
表限定列以消除任何歧义。给定的示例在这方面实际上是草率且不一致的,对某些列进行了表限定,但对其他列进行了限定。如果它是这样明确的,它就不会误导你:
它没有添加到表中。您可以添加具有查询本身中定义的值的字段。它们只是结果的一部分,不会添加到表中。