首页 > 解决方案 > 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 语法不应该支持它吗?如果不支持,为什么不呢?

标签: sqljoinmariadbleft-joininner-join

解决方案


不要混合隐式和显式连接!当你这样做时会发生不好的事情,因为不同类型的连接有不同的优先规则:首先评估显式连接,这会导致你得到错误。在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

推荐阅读