SQL问题——select across multiple tables (user groups)

标签 sql

我有一个看起来像这样的数据库模式:

create table user         (id int, name varchar(32));
create table group        (id int, name varchar(32));
create table group_member (group_id int, user_id int, flag int);

我想编写一个允许我执行以下操作的查询:

给定一个有效的用户 ID (UID),获取与指定用户 ID (UID) 在同一组中且 group_member.flag=3 的所有用户的 ID。

而不是只有 SQL。我想学习如何像 Db 程序员一样思考。作为一名编码员,SQL 是我最薄弱的环节(因为我对命令式语言比声明式语言更舒服)——但我想改变它。

无论如何,这里是我确定的分解任务所必需的步骤。如果一些 SQL 大师可以演示简单的 SQL 语句,我将不胜感激 - 即原子 SQL 语句,一个用于下面确定的每个子任务,然后最后,我如何组合这些语句来制作实现所需功能的 ONE 语句。

这里是(假设指定的 user_id [UID] = 1):

//Subtask #1.
Fetch list of all groups of which I am a member

Select group.id from user inner join group_member where user.id=group_member.user_id and user.id=1

//Subtask #2
Fetch a list of all members who are members of the groups I am a member of (i.e. groups in subtask #1)

Not sure about this ...

select user.id from user, group_member gm1,  group_member gm2, ... [Stuck]

//Subtask #3
Get list of users that satisfy criteria group_member.flag=3
Select user.id from user inner join group_member where user.id=group_member.user_id and user.id=1 and group_member.flag=3

一旦我有了子任务 2 的 SQL,我就会想看看如何从这些子任务构建完整的 SQL 语句(您不必在子任务中使用 SQL,它只是一种解释所涉及步骤的方式 -另外,我的 SQL 可能不正确/效率低下,如果是这样,请随时更正它,并指出它有什么问题)。

谢谢

最佳答案

查询 1 - 选择我所属的所有组。

除非您还想要群组的名称,否则您不需要在此处加入。只需检查 group_member 表即可。

SELECT group_id
FROM group_member
WHERE user_id = 1

结果:

1
3

查询 2:选择与我属于同一组的所有用户。

你可以自己加入group_member表,找出所有属于同一组的用户,然后添加一个where子句,只找出所有属于你自己的组。添加 DISTINCT 以确保您不会两次获得人员。

SELECT DISTINCT T2.user_id
FROM group_member AS T1
JOIN group_member AS T2
ON T1.group_id = T2.group_id
WHERE T1.user_id = 1
AND T2.user_id <> 1 -- Remove myself

结果:

2
3
5

查询 3:在任何组中具有标记 3 的用户。

您只需要检查group_member 表。同样,如果您只想看到每个用户一次,请添加 DISTINCT

SELECT DISTINCT user_id
FROM group_member
WHERE group_member.flag=3

结果:

2
3
4

最终查询:和我同组的flag 3的用户。

这和查询二几乎一样,只是多加了一个WHERE条件。

SELECT DISTINCT T2.user_id
FROM group_member AS T1
JOIN group_member AS T2
ON T1.group_id = T2.group_id
WHERE T1.user_id = 1
AND T2.user_id <> 1 -- Remove myself
AND T2.flag = 3

结果:

2
3

测试数据:

create table user         (id int, name varchar(32));
create table `group`        (id int, name varchar(32));
create table group_member (group_id int, user_id int, flag int);

insert into user (id, name) VALUES (1, 'user1'), (2, 'user2'), (3, 'user3'), (4, 'user4'), (5, 'user5');
insert into `group` (id, name) VALUES (1, 'group1'),(2, 'group2'), (3, 'group3');
insert into group_member (group_id, user_id, flag) VALUES (1, 1, 0), (1, 2, 3), (1, 3, 3), (2, 3, 3), (2, 4, 3), (2, 5, 0), (3, 1, 0), (3, 5, 0);

关于SQL问题——select across multiple tables (user groups),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2659365/

相关文章:

SQL Server : Find rows in table where both columns not sequential

python - 如何在 3 个表上的 SQLAlchemy 中执行 JOIN,其中一个在其他两个表之间进行映射?

sql - 如何在 PostgreSQL 中创建只读用户?

sql - 获取所有表的 MySQL 模式

C#构造参数查询SQL - LIKE %

java - 过滤请求JPQL(查找列表中不包含具有特定id的元素的条目)

sql - 在 SQL Server 中拆分以空格分隔的值列表

sql - Django Queryset __in 在列表中没有值

php - Laravel 4 Eloquent 返回错误的 ID

sql - Oracle SQL : Calculate value using previous row