【问题标题】:MySQL join 3 tables and find "missing" rows in one tableMySQL 连接 3 个表并在一个表中找到“丢失”的行
【发布时间】:2016-08-14 15:12:17
【问题描述】:

我在 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

当查询完成时,它会返回一个巨大的用户名和小部件名称列表,但比我预期的要多数百个。

我不确定连接是否错误,或者我是否需要对结果进行某种分组?

【问题讨论】:

  • 你得到了什么结果?请将其包含在您的答案中或设置 SQL Fiddle。

标签: mysql join not-exists


【解决方案1】:

试试下面的,对我有用。

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);

【讨论】:

    【解决方案2】:

    您可以使用笛卡尔积和一些内连接

    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;
    

    【讨论】:

      【解决方案3】:

      这是这种查询背后的想法。首先生成用户和小部件的所有可能组合。然后过滤掉那些存在的:

      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 表中的tenant_id。但是,我不确定这是否有很大的不同。

      【讨论】:

      • 我使用了它,它给出了正确的结果 - 我注意到的另一件事是您使用的是联接,但我使用的是左联接,这会有所不同吗?
      • @bhttoan 。 . .如果您的用户根本没有小部件,那么这将解释差异。
      猜你喜欢
      • 2016-12-09
      • 1970-01-01
      • 1970-01-01
      • 2013-06-30
      • 1970-01-01
      • 2013-04-07
      • 2013-04-21
      • 2023-03-03
      • 1970-01-01
      相关资源
      最近更新 更多