SQLite JOIN ... USING - rowid 有效,但随后不起作用

Kev*_*vin 5 join

这有效。

SELECT *
FROM Demographics
JOIN MeasuresofBirthAndDeath
ON Demographics.rowid = MeasuresofBirthAndDeath.rowid;
Run Code Online (Sandbox Code Playgroud)

这不。

SELECT *
FROM Demographics 
JOIN MeasuresofBirthandDeath
USING (rowid);
Run Code Online (Sandbox Code Playgroud)

为什么?

ale*_*dov 4

看来这样的查询对于显式主键工作得很好。我运行这段代码:

CREATE TABLE Demographics (rowid int PRIMARY KEY);
CREATE TABLE MeasuresofBirthAndDeath (rowid int PRIMARY KEY);

insert into Demographics VALUES (1);
insert into MeasuresofBirthAndDeath VALUES (1);
insert into MeasuresofBirthAndDeath VALUES (2);

SELECT * FROM Demographics JOIN MeasuresofBirthandDeath USING (rowid);
Run Code Online (Sandbox Code Playgroud)

并得到正确的结果:1

如果使用隐式 rowid,它确实不起作用。我们看一下代码:

CREATE TABLE Demographics (name text);
CREATE TABLE MeasuresofBirthAndDeath (name text);

insert into Demographics VALUES ('demo');
insert into MeasuresofBirthAndDeath VALUES ('birth');
insert into MeasuresofBirthAndDeath VALUES ('death');

SELECT * FROM Demographics JOIN MeasuresofBirthandDeath USING (rowid);
Error: cannot join using column rowid - column not present in both tables
Run Code Online (Sandbox Code Playgroud)

我们收到错误,因为 rowid 不是真正的列(https://www.sqlite.org/lang_createtable.html#rowid):

除了WITHOUT ROWID 表之外,SQLite 表中的所有行都有一个 64 位带符号整数键,用于唯一标识表中的行。该整数通常称为“rowid”。可以使用与大小写无关的特殊名称“rowid”、“oid”或“ rowid ”之一代替列名称来访问 rowid 值。如果表包含名为“rowid”、“oid”或“ rowid ”的用户定义列,则该名称始终引用显式声明的列,并且不能用于检索整数 rowid 值。

在第一个选择中,我们明确添加条件来加入并且它有效

ON Demographics.rowid = MeasuresofBirthAndDeath.rowid
Run Code Online (Sandbox Code Playgroud)

但在第二个选择中,两个表中都没有列可对其应用 USING。

您可以更改表并创建 INTEGER PRIMARY KEY 列(这将是 rowid 的别名)并在这些新列上使用 JOIN USING :

如果 rowid 表的主键由单个列组成,并且该列的声明类型为大小写任意混合的“INTEGER”,则该列将成为 rowid 的别名。这样的列通常称为“整数主键”。如果声明的类型名称恰好是“INTEGER”,则主键列仅成为整数主键。其他整数类型名称(例如“INT”或“BIGINT”或“SHORT INTEGER”或“UNSIGNED INTEGER”)会导致主键列表现为具有整数关联性和唯一索引的普通表列,而不是作为 rowid 的别名。