【问题标题】:MariaDB JOIN syntax [duplicate]MariaDB JOIN 语法 [重复]
【发布时间】:2020-10-06 22:11:37
【问题描述】:

我正在尝试从三个链接表(多对多关系)中选择一些记录,然后 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 语法不应该支持吗?如果不支持,为什么不支持?

【问题讨论】:

  • 请在代码问题中给出minimal reproducible example--cut & paste & runnable code,包括最小的代表性示例输入作为代码;期望和实际输出(包括逐字错误消息);标签和版本;明确的规范和解释。给出尽可能少的代码,即您显示的代码可以通过您显示的代码扩展为不正常的代码。 (调试基础。)对于包含 DBMS 和 DDL(包括约束和索引)的 SQL,并以表格格式作为代码输入。 How to Ask 暂停总体目标的工作,将代码砍到第一个表达式,没有给出你期望的内容,说出你期望的内容和原因。
  • 这是一个常见问题解答。谷歌搜索您的错误消息,您的问题将在答案中。如果您在准备 MRE 时将代码缩减到最低限度,那么 select * from u , a join r 仍然会返回您不期望的内容,并且您可以使用 google re comma plus join。请在考虑发布之前阅读您的教科书和/或手册和谷歌任何错误消息或您的问题/问题/目标的许多清晰、简洁和精确的措辞,有和没有您的特定字符串/名称和站点:stackoverflow.com 和标签;阅读许多答案。反映你的研究。请参阅How to Ask 和投票箭头鼠标悬停文本。
  • 逗号表示交叉连接,但优先级低于关键字连接。因此,首先完成 JOIN ON 并且在那里不知道逗号的左表。所以不要将逗号与关键字连接混合使用。 PS你有一个语法错误。阅读语法和手册。显示组成子表达式是好的。

标签: sql join mariadb left-join inner-join


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-29
    • 1970-01-01
    • 1970-01-01
    • 2020-02-25
    • 2021-09-17
    • 2012-08-12
    • 2016-02-16
    • 1970-01-01
    相关资源
    最近更新 更多