标识符
与其他SQL方言和编程语言类似,DuckDB的SQL中的标识符也遵循一些规则。
- 未加引号的标识符需要符合一些规则:
- 它们不能是保留关键字(参见
duckdb_keywords()
),例如,SELECT 123 AS SELECT
将会失败。 - 它们不能以数字或特殊字符开头,例如,
SELECT 123 AS 1col
是无效的。 - 它们不能包含空格(包括制表符和换行符)。
- 它们不能是保留关键字(参见
- 标识符可以使用双引号字符(
"
)进行引用。被引用的标识符可以使用任何关键字、空格或特殊字符,例如,"SELECT"
和" § 🦆 ¶ "
是有效的标识符。 - 双引号可以通过重复引号字符来转义,例如,要创建一个名为
IDENTIFIER "X"
的标识符,请使用"IDENTIFIER ""X"""
。
去重标识符
在某些情况下,可能会出现重复的标识符,例如,在展开嵌套数据结构时,列名可能会发生冲突。 在这些情况下,DuckDB 会根据以下规则自动去重列名:
- 对于名为
⟨name⟩
的列,第一个实例不会被重命名。 - 后续实例将被重命名为
⟨name⟩_⟨count⟩
,其中⟨count⟩
从1开始。
例如:
SELECT *
FROM (SELECT UNNEST({'a': 42, 'b': {'a': 88, 'b': 99}}, recursive := true));
a | a_1 | b |
---|---|---|
42 | 88 | 99 |
数据库名称
数据库名称遵循标识符的规则。
此外,最佳实践是避免使用DuckDB的两个内部数据库模式名称,system
和 temp
。
默认情况下,持久数据库以其文件名命名,不带扩展名。
因此,文件名 system.db
和 temp.db
(以及 system.duckdb
和 temp.duckdb
)分别会导致数据库名称为 system
和 temp
。
如果您需要附加到具有这些名称之一的数据库,请使用别名,例如:
ATTACH 'temp.db' AS temp2;
USE temp2;
大小写规则
关键词和函数名称
在DuckDB中,SQL关键字和函数名称不区分大小写。
例如,以下两个查询是等价的:
select COS(Pi()) as CosineOfPi;
SELECT cos(pi()) AS CosineOfPi;
余弦值π |
---|
-1.0 |
标识符的大小写敏感性
DuckDB中的标识符始终不区分大小写,类似于PostgreSQL。 然而,与PostgreSQL(以及其他一些主要的SQL实现)不同,DuckDB也将带引号的标识符视为不区分大小写。
尽管以不区分大小写的方式处理标识符,但每个字符的大小写(大写/小写)仍保持用户最初指定的形式,即使查询在引用标识符时使用不同的大小写。 例如:
CREATE TABLE tbl AS SELECT cos(pi()) AS CosineOfPi;
SELECT cosineofpi FROM tbl;
余弦值Pi |
---|
-1.0 |
要更改此行为,请将配置选项 preserve_identifier_case
设置为 false
。
处理冲突
在发生冲突的情况下,当相同的标识符以不同的大小写拼写时,将随机选择一个。例如:
CREATE TABLE t1 (idfield INTEGER, x INTEGER);
CREATE TABLE t2 (IdField INTEGER, y INTEGER);
INSERT INTO t1 VALUES (1, 123);
INSERT INTO t2 VALUES (1, 456);
SELECT * FROM t1 NATURAL JOIN t2;
id字段 | x | y |
---|---|---|
1 | 123 | 456 |
禁用保留案例
当preserve_identifier_case
配置选项设置为false
时,所有标识符都将转换为小写:
SET preserve_identifier_case = false;
CREATE TABLE tbl AS SELECT cos(pi()) AS CosineOfPi;
SELECT CosineOfPi FROM tbl;
cosineofpi |
---|
-1.0 |