JOIN上的子查询以提取所有ID /名称

时间:2015-06-10 19:45:45

标签: mysql

* user
user_id
name

* client
client_id
name

* user_client
user_client_id
user_id
client_id

* message
message_id
client_id
description

样本表行

user_id 
1
2
3

client_id   name
10          John
11          James
12          David
13          Richard
14          Bob

user_client
user_id    client_id
1          11
1          13
3          14
3          10

message
message_id    client_id    message
1             11           Hello Word
2             12           MySQL is awesome
3             14           I like StackOverflow
4             13           This is very cool

当我使用该查询作为LEFT JOIN上的子查询来仅为那些与用户相关的客户端提取消息时,它无法正常工作。

有什么想法吗?

谢谢!

3 个答案:

答案 0 :(得分:0)

设置示例的DDL(在MySQL中)和我认为您正在寻找的查询如下所示。

/*

-- DDL TO SET UP EXAMPLE

create schema example;

use example;

create table user (
    user_id int,
    name varchar(64)
);

create table client(
    client_id int,
    name varchar(64)
);

create table user_client (
    user_client_id int,
    user_id int,
    client_id int
);


create table message(
    message_id int,
    client_id int,
    message varchar(64)
);

insert into user values (1, 'Peter');
insert into user values (2, 'Paul');
insert into user values (3, 'Mary');

insert into client values (10, 'John');
insert into client values (11, 'James');
insert into client values (12, 'David');
insert into client values (13, 'Richard');
insert into client values (14, 'Bob');

insert into user_client values (1, 1, 11);
insert into user_client values (2, 1, 11);
insert into user_client values (3, 3, 14);
insert into user_client values (4, 3, 10);

insert into message values (1, 11, 'Hello World');
insert into message values (2, 12, 'MySQL is awesome');
insert into message values (3, 14, 'I like StackOverflow');
insert into message values (4, 13, 'This is very cool');

*/

-- query to get all messages for all clients of a given user

select 
    *
from
    user_client uc
    join user u on uc.user_id = u.user_id
    join client c on uc.client_id = c.client_id
    join message m on m.client_id = c.client_id
where 
    u.user_id = 1;

-- query to get all messages for a given client

select 
    *
from
    user_client uc
    join user u on uc.user_id = u.user_id
    join client c on uc.client_id = c.client_id
    join message m on m.client_id = c.client_id
where 
    c.client_id = 11;

答案 1 :(得分:0)

我的原始ddl在其中一个插件中出现了错误(下面已修复)。在下面的sql中,我还添加了一个没有消息的用户。我相信下面发布的内容的查询是您正在寻找的。

-- DDL TO SET UP EXAMPLE

drop schema example;

create schema example;

use example;

create table user (
    user_id int,
    name varchar(64)
);

create table client(
    client_id int,
    name varchar(64)
);

create table user_client (
    user_client_id int,
    user_id int,
    client_id int
);


create table message(
    message_id int,
    client_id int,
    message varchar(64)
);

insert into user values (1, 'Peter');
insert into user values (2, 'Paul');
insert into user values (3, 'Mary');

insert into client values (10, 'John');
insert into client values (11, 'James');
insert into client values (12, 'David');
insert into client values (13, 'Richard');
insert into client values (14, 'Bob');
insert into client values (15, 'Quiet Client');

insert into user_client values (1, 1, 11);
insert into user_client values (2, 1, 13);
insert into user_client values (3, 3, 14);
insert into user_client values (4, 3, 10);
insert into user_client values (5, 1, 15);

insert into message values (1, 11, 'Hello World');
insert into message values (2, 12, 'MySQL is awesome');
insert into message values (4, 13, 'This is very cool');
insert into message values (3, 14, 'I like StackOverflow');

-- query to get all messages for all clients of a given user

select 
    u.user_id,
    u.name user_name,
    c.client_id,
    c.name client_name,
    m.message
from
    user_client uc
    join user u on uc.user_id = u.user_id
    join client c on uc.client_id = c.client_id
    left outer join message m on m.client_id = c.client_id
where 
    u.user_id = 1;

输出:

+ ------------ + -------------- + -------------- + ---------------- + ------------ +
| user_id      | user_name      | client_id      | client_name      | message      |
+ ------------ + -------------- + -------------- + ---------------- + ------------ +
| 1            | Peter          | 11             | James            | Hello World  |
| 1            | Peter          | 13             | Richard          | This is very cool |
| 1            | Peter          | 15             | Quiet Client     |              |
+ ------------ + -------------- + -------------- + ---------------- + ------------ +
3 rows

答案 2 :(得分:0)

这应该是三个单独的查询,因为根据评论提出了三个不同的问题:

  

所以你想要一个会从相关客户端返回消息的查询   客户端中有记录,如果没有记录,则显示所有消息   给用户的客户? - 约翰

...

  

你好@John是正确的。这就是我使用子查询的原因,   因为它完全拉动了,但由于某种原因,client_id和   对于除一个之外的所有名称,名称将为NULL。 - Kitara

第一个问题(查询)是查找给定用户的所有客户端的所有消息。

第二个问题(查询)是:用户是否具有查看所有消息的“授权”。如果用户没有客户端,则该用户被“授权”查看所有消息。

第三个问题(查询)是:如果用户有权查看所有消息,则获取所有消息。

这些是非常简单的直接查询,可以编写,执行和理解。尝试将所有这些混合到单个查询中会增加复杂性并且表示关注点差。如果执行三个非常简单的查询表示性能问题,则需要重新考虑应用程序的体系结构。