【问题标题】:Mysql Left Join on multiple conditionsMysql Left Join 在多个条件下
【发布时间】:2013-12-09 13:39:14
【问题描述】:

我有两个表如下: 用户表:

CREATE TABLE `user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
    PRIMARY KEY (`id`)      
);

另外一个表为 uep,如下:

CREATE TABLE `uep` (
  `user_id` int(10) unsigned NOT NULL,
  `email_template_id` int(10) unsigned NOT NULL,
  `sid` int(10) unsigned NOT NULL,
  `send_email` tinyint(1) NOT NULL DEFAULT '1'
);

我想从用户表中获取所有记录,并且只有在
user.id = uep.user_id AND uep.send_email = 0

时才将left 加入到uep 表中

但是当我运行查询时

Select id, group_concat(email_template_id) as T from user
LEFT join uep ON (user.id = uep.user_id AND uep.send_email = 0)
group by user_id limit 100

它会忽略用户表中 send_email = 1 的用户。

我只想在 user.id 和 send_email =0 时加入 uep 表,否则不应该加入,只返回用户详细信息。

Sql 小提琴:http://www.sqlfiddle.com/#!2/1f083/2

任何帮助!

【问题讨论】:

  • user是mysql中的保留字吗?它在 TSQL 中,这在 SQL Server 中不起作用,当您使用 ...as T from [user]... 时
  • @DanielDyson: user 不是保留关键字。
  • @SureshKamrushi 请提供一个包含所需结果的表格。我不明白,你想得到什么。
  • 您说 uep.send_email = 0 但随后您抱怨忽略了 uep.send_email = 1.Clarify 的用户。
  • 小提琴用户表中没有 send_email 字段

标签: mysql join left-join


【解决方案1】:

试试

Select 
    id, group_concat(email_template_id) as T 
from 
    user
LEFT join 
    uep 
ON 
  (user.id = uep.user_id AND uep.send_email = 0)
OR
  (uep.send_email = 1 AND user.id = uep.user_id)
group by 
  user_id 
limit 
  100;

http://www.sqlfiddle.com/#!2/6c28ee/1 上的演示

【讨论】:

  • 值得注意的是,虽然这有效,但您应该小心这样做,因为它可能是一个非常慢的查询,因为结果是次优的表扫描。您应该考虑在连接条件中使用 IF - wandi-studio.com/Laboratory/Entry/Item/…
【解决方案2】:

由于“分组依据”条件,您的查询返回错误结果。只需将 group by user_id 更改为 id 如下所述:

Select id, group_concat(email_template_id) as T from user
LEFT join uep ON (user.id = uep.user_id AND uep.send_email = 0)
group by id limit 100

【讨论】:

    【解决方案3】:

    您在帖子中提到它忽略了 send_email = 1 的用户。它应该有他们,因为用户是联接的 LEFT-basis,但是,它的“T”值将是空白的,因为您的 LEFT-JOIN 只关心 0价值观。那么,你想要什么......两列?一个发送电子邮件 = 0,另一个发送电子邮件 = 1?

    Select 
          u.id, 
          COALESCE( UEP0.T, '' ) T,
          COALESCE( UEP1.T, '' ) T1
       from 
          user u
             LEFT join ( select uep.user_id,
                                group_concat( uep.email_template_id ) as T
                            from
                               uep
                            where
                               uep.send_email = 0
                            group by
                               uep.user_id ) UEP0
                ON (u.id = UEP0.user_id)
             LEFT join ( select uep.user_id,
                                group_concat( uep.email_template_id ) as T
                            from
                               uep
                            where
                               uep.send_email = 1
                            group by
                               uep.user_id ) UEP1
                ON (u.id = UEP1.user_id)
       limit 
          100
    

    此版本同时获得两个版本...左连接与 UEP 表分开,为各自的 send_email 状态为 0 或 1 执行自己的组 concat()。因此用户表连接到两个结果并获得任一版本,现在您可以使用相应的模板 ID 为所欲为。

    【讨论】:

      【解决方案4】:

      您不必将它包含在 ON 子句中。您可以简单地添加一个 WHERE 子句:

      Select id, group_concat(email_template_id) as T from user
      LEFT join uep ON (user.id = uep.user_id)
      WHERE uep.send_email = 0
      group by user_id limit 100
      

      【讨论】:

      • 它将忽略 send_email = 1 的用户。
      • 你能解释一下吗? User 表只有 idname 列。我没有看到任何send_email 列。
      • 这实际上是一个 INNER JOIN。来自用户的任何行如果没有来自 uep 的匹配行将在 uep.send_email 中具有 NULL,因此将被 WHERE 子句丢弃。
      • @Kickstart:是的。我只想在 user.id 和 send_email =0 时加入 uep 表,否则不应该加入,只返回用户详细信息。
      • 在这种情况下,您现有的 SQL 可以工作。 Andrei 的建议只会返回 send_email 为 0 的用户,其他任何人都将被忽略,因为它实际上是在进行 INNER JOIN。
      【解决方案5】:

      对不起,现在没有时间做小提琴,但这样的事情应该适合你。

      Select id, u2.T from user
      LEFT join 
      ( Select `user_id`, group_concat(email_template_id) as T 
        From uep
        Where uep.send_email = 0
      ) u2
      On user.id = u2.user_id 
      group by user_id limit 100
      

      【讨论】:

        猜你喜欢
        • 2013-05-14
        • 1970-01-01
        • 2020-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-10
        • 1970-01-01
        相关资源
        最近更新 更多