【问题标题】:Mysql Query Left Join Condition ProblemMysql查询左连接条件问题
【发布时间】:2010-10-15 18:41:43
【问题描述】:

我有一个 mysql 查询的小问题。

我用了 5 张桌子:

user_has_data (uid, dataid);用户(uid,uname); user_in_group(uid, groupid, 数据);组(组ID,数据,包ID);包(packageid,名称)

所有 id 都是 PK。我想构建一个sql查询,通过其uname查找属于指定dataid的用户,并检查用户是否在属于指定包的组(表user_in_group中的关系)中(一个组分配给一个包)。如果是,则应从用户、包和组中获取数据,否则应仅获取用户数据。因此我使用左连接,所以我也可以得到没有组的用户:

SELECT `uac`.`uid`, `u`.`uid`, `uig`.`groupid`, `ag`.`packageid` 
FROM `user_has_data` AS `uac` 
INNER JOIN `users` AS `u` ON u.uid = uac.uid 
LEFT JOIN `user_in_group` AS `uig` ON uig.uid = uac.uid 
LEFT JOIN `groups` AS `ag` ON (ag.groupid = uig.groupid) AND (ag.packageid = 2) 
WHERE (uac.dataid = '3') AND (u.uname LIKE 'test%')
GROUP BY `u`.`uid`

不幸的是,我得到了错误的结果:如果用户有另一个具有不同 packageid 的组分配给他,我得到的组的 packageid 与加入中所述的不同。

这可能是因为第一个左连接对 packageid 没有限制,第二个是左连接,所以它对结果没有限制(对于所有结果,packageid 都是 NULL,但应该有值)。如果我将第二个左连接更改为普通连接,组问题将得到解决,但查询无法再找到没有组的用户。

任何想法如何解决这个甚至可能? 提前致谢!

【问题讨论】:

    标签: mysql join


    【解决方案1】:

    您是说您实际上在查询结果中看到了值 ag.packageid = 2?

    如果没有,我认为您可以尝试以下方法:

    SELECT `uac`.`uid`, `u`.`uid`, `g`.`groupid`, `g`.`packageid` 
    FROM `user_has_data` AS `uac` 
    INNER JOIN `users` AS `u` ON u.uid = uac.uid 
    LEFT JOIN (`user_in_group` AS `uig` 
      INNER JOIN `groups` AS `ag` ON (ag.groupid = uig.groupid) AND (ag.packageid = 2) )
     AS `g` ON uac.uid = g.uid
    WHERE (uac.dataid = '3') AND (u.uname LIKE 'test%')
    GROUP BY `u`.`uid`
    

    【讨论】:

      【解决方案2】:

      因为您将搜索限制为“2”的特定组 packageid,为什么不直接将两个 LEFT JOIN INNER JOINS 都放入,然后在 WHERE 子句中输入 ag.packageid = 2?

      【讨论】:

      • 如果两个连接都是 INNER JOIN,则查询无法再找到没有组的用户(但它也应该找到那种用户)
      【解决方案3】:
      SELECT `uac`.`uid`, `u`.`uid`, `uig`.`groupid`, `ag`.`packageid` 
      FROM `user_has_data` AS `uac` 
      INNER JOIN `users` AS `u` ON u.uid = uac.uid 
      LEFT OUTER JOIN `user_in_group` AS `uig` ON uig.uid = uac.uid 
      LEFT OUTER JOIN `groups` AS `ag` ON ag.groupid = uig.groupid
      WHERE (uac.dataid = '3') AND (u.uname LIKE 'test%')
      AND (ag.packageid = 2 OR uig.uid IS NULL) 
      GROUP BY `u`.`uid`
      

      我知道 LEFT JOIN 和 LEFT OUTER JOIN 是同一个意思,但我喜欢明确一点。根据您加入的条件,我敢打赌,您获得了包含不同套餐的群组,但没有收到套餐?

      【讨论】:

      • 感谢您的回答。实际上它改善了结果,但它只获得了没有组的用户(如果我实现正确的话)......
      • 我没有注意 GROUP BY。删除后会得到什么?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-04
      • 2011-03-12
      • 1970-01-01
      • 2018-11-19
      • 2014-03-04
      相关资源
      最近更新 更多