MySQL 加入 3 table 并在一个 table 中找到 "missing" 行
MySQL join 3 tables and find "missing" rows in one table
我在 MySQL 中有 3 个表,我需要找到用户没有特定小部件的所有实例。
示例:
Users
tenant_id user_id user_name
1 1 Bob
1 2 Fred
1 3 John
1 4 Tom
Widgets
tenant_id widget_id widget_name
1 1 Red
1 2 Blue
1 3 Green
1 4 Black
Usage
tenant_id user_id widget_id
1 1 1
1 1 2
1 1 4
1 2 2
1 2 3
1 2 4
1 3 1
1 3 2
1 3 3
1 3 4
1 4 1
1 4 2
1 4 3
Missing in table three are:
user_name widget_name
Bob Green
Fred Red
Tom Black
我尝试使用的查询是:
SELECT
user_name, widget_name
FROM
users left join widgets on users.tenant_id=widgets.tenant_id
WHERE
NOT EXISTS (
SELECT 1 FROM usage WHERE user_id = users.user_id AND widget_id = widgets.widget_id
) and users.tenant_id=1
查询完成后,它会返回一个巨大的用户名和小部件名称列表,但比我预期的要多数百个。
我不确定连接是否错误或者我是否需要对结果进行某种分组?
下面是此类查询背后的想法。首先生成用户和小部件的所有可能组合。然后过滤掉存在的:
select u.user_name, w.widget_name
from users u join
widgets w
on u.tenant_id = w.tenant_id
where not exists (select 1
from usage us
where us.user_id = u.user_id and us.widget_id = w.widget_id and
us.tenant_id = u.tenant_id
) and
u.tenant_id = 1;
我认为您的逻辑缺少 usage
table 中的 tenant_id
。但是,我不确定这是否有很大的不同。
你可以使用笛卡尔积和一些内连接
select b.user_name, c.widget_name
from
( select u.user_id, w.widget_id
from Users as u, Widgets as w
where (u.user_id, w.widget_id) not in (select user_id, widget_id
from Usage)) as a
inner join Users as b on a.user_id = b.user_id
inner join Widgets as c on a.widget_id = c.widget_id;
试试下面的,对我有用。
select w.widget_name, u.user_name
from widgets w join users u on w.tenant_id = u.tenant_id
where (w.widget_name, u.user_name ) not in
(select w.widget_name, u.user_name
from widgets w join `usage` us on us.widget_id = w.widget_id
join users u on u.user_id = us.user_id);
我在 MySQL 中有 3 个表,我需要找到用户没有特定小部件的所有实例。
示例:
Users
tenant_id user_id user_name
1 1 Bob
1 2 Fred
1 3 John
1 4 Tom
Widgets
tenant_id widget_id widget_name
1 1 Red
1 2 Blue
1 3 Green
1 4 Black
Usage
tenant_id user_id widget_id
1 1 1
1 1 2
1 1 4
1 2 2
1 2 3
1 2 4
1 3 1
1 3 2
1 3 3
1 3 4
1 4 1
1 4 2
1 4 3
Missing in table three are:
user_name widget_name
Bob Green
Fred Red
Tom Black
我尝试使用的查询是:
SELECT
user_name, widget_name
FROM
users left join widgets on users.tenant_id=widgets.tenant_id
WHERE
NOT EXISTS (
SELECT 1 FROM usage WHERE user_id = users.user_id AND widget_id = widgets.widget_id
) and users.tenant_id=1
查询完成后,它会返回一个巨大的用户名和小部件名称列表,但比我预期的要多数百个。
我不确定连接是否错误或者我是否需要对结果进行某种分组?
下面是此类查询背后的想法。首先生成用户和小部件的所有可能组合。然后过滤掉存在的:
select u.user_name, w.widget_name
from users u join
widgets w
on u.tenant_id = w.tenant_id
where not exists (select 1
from usage us
where us.user_id = u.user_id and us.widget_id = w.widget_id and
us.tenant_id = u.tenant_id
) and
u.tenant_id = 1;
我认为您的逻辑缺少 usage
table 中的 tenant_id
。但是,我不确定这是否有很大的不同。
你可以使用笛卡尔积和一些内连接
select b.user_name, c.widget_name
from
( select u.user_id, w.widget_id
from Users as u, Widgets as w
where (u.user_id, w.widget_id) not in (select user_id, widget_id
from Usage)) as a
inner join Users as b on a.user_id = b.user_id
inner join Widgets as c on a.widget_id = c.widget_id;
试试下面的,对我有用。
select w.widget_name, u.user_name
from widgets w join users u on w.tenant_id = u.tenant_id
where (w.widget_name, u.user_name ) not in
(select w.widget_name, u.user_name
from widgets w join `usage` us on us.widget_id = w.widget_id
join users u on u.user_id = us.user_id);