sql - MariaDB JOIN 语法
问题描述
我正在尝试从三个链接表(多对多关系)中选择一些记录,然后left join
选择另一个表的结果。我收到以下错误:
#1054 - Unknown column 'u.id' in 'on clause'
这是引发该错误的查询的完整示例:
drop database if exists example1;
create database example1;
use example1;
create table users (id integer not null auto_increment primary key, name varchar(50));
insert into users (name) values ('Alice'),('Bob'),('Carol');
create table roles (id integer not null auto_increment primary key, role varchar(50));
insert into roles (role) values ('developer'),('hr'),('sales');
create table users_roles (user_id integer, role_id integer);
insert into users_roles (user_id, role_id) values (1,1),(1,2),(2,3),(3,2);
create table activity (id integer not null auto_increment primary key, user_id integer not null, description varchar (200));
insert into activity (user_id, description) values (1, 'logged in'), (1, 'logged out'), (2, 'changed password');
SELECT u.name AS 'Username',
a.description AS 'Activity',
r.role AS 'Role'
FROM users u, users_roles ur, roles r
LEFT JOIN activity a ON a.user_id = u.id
WHERE ur.role_id = r.id AND ur.user_id = u.id;
经过几次测试,我得出的结论是,问题在于子句中列出了多个表,FROM
然后在其后面加上LEFT JOIN
. 所以我想我应该写这个:
[...]
SELECT u.name AS 'Username',
a.description AS 'Activity',
r.role AS 'Role'
FROM users u
JOIN users_roles ur ON ur.user_id = u.id
JOIN roles r ON r.id = ur.role_id
LEFT JOIN activity a ON a.user_id = u.id
事实上,这确实按预期工作。我的问题是:我的第一个版本有什么问题SELECT
?MySQL 语法不应该支持它吗?如果不支持,为什么不呢?
解决方案
不要混合隐式和显式连接!当你这样做时会发生不好的事情,因为不同类型的连接有不同的优先规则:首先评估显式连接,这会导致你得到错误。在left join
解释 时,还没有看到隐式连接中定义的别名。
事实上,在所有查询中始终如一地使用显式标准连接:隐式连接是遗留语法,不应在新代码中使用。
SELECT u.name AS Username,
a.description AS Activity,
r.role AS Role
FROM users u
INNER JOIN users_roles ur ON ur.user_id = u.id
INNER JOIN roles r ON r.id = ur.role_id
LEFT JOIN activity a ON a.user_id = u.id
推荐阅读
- java - 为什么 Java 有 4 种不同类型的引用?
- user-interface - 如何从 Pymel LayoutDialog 获得用户选择?
- react-native - React Native FlatList 逐字符呈现数据
- python - 加快新特征的计算(关于时间和对象的行的循环)
- google-sheets-api - 未应用第二次更改 userEnteredFormat
- python-3.x - 如何使用 pandas 修改数据列值?
- python - YA 层 model_20 需要 2 个输入,但它接收到 3 个输入张量
- python - 逻辑回归模型的损失不会通过梯度下降而减少
- laravel - 要查看的 Laravel 数组
- c# - C# ASP .NET Web API 依赖注入将当前控制器的属性传递给服务类构造函数