【问题标题】:Mysql SELECT only unique values in one column when left joined with another table当与另一张表左连接时,Mysql SELECT 仅在一列中的唯一值
【发布时间】:2017-09-25 12:23:51
【问题描述】:

这是查询:

SELECT a.id, a.userName,if(o.userId=1,'C',if(i.userId=1,'I','N')) AS relation 
       FROM tbl_users AS a 
       LEFT JOIN tbl_contacts AS o ON a.id = o.contactId 
       LEFT JOIN tbl_invites AS i ON a.id = i.invitedId 
  ORDER BY relation

这将返回如下输出:

+----+--------------+-------------+
| ID | USERNAME     | RELATION    | 
+----+--------------+-------------+
|  1 |          ray |           C | 
+----+--------------+-------------+
|  2 |         john |           I | 
+----+--------------+-------------+
|  1 |         ray  |           N | 
+----+--------------+-------------+

我需要通过检查 id 是否重复来从选择查询中删除第三行。优先级如下:

C -> I -> N。因此,既然已经有一个带有 C 的“射线”,我不想再用 I 或 N 了。

我尝试添加 distinct(a.id) 但它不起作用。我该怎么做呢?

为什么 DISTINCT 对此不起作用?

【问题讨论】:

  • 你想对关系做什么? 1 ray C/N C 和 N 有两种不同的关系。确定要扔掉第三行吗?
  • 是的,我确定。优先级如下 C -> I -> N。因此,如果有一个具有用户 ID 的 C,那么我不想要一个具有相同用户 ID 的 N
  • 你能帮帮我吗?任何建议将不胜感激。
  • 研究 MySQL GROUP BY clause.
  • @rams。问题中没有指出,但这是你提出的一个好观点。重新打开并回答问题。

标签: mysql select distinct


【解决方案1】:

根据您提供的规范,您所要做的就是按 ID 和用户名分组,然后选择您能找到的最低关系值(因为 C < I < N

SELECT a.id, a.userName, MIN(if(o.userId=1,'C',if(i.userId=1,'I','N'))) AS relation 
    FROM tbl_users AS a 
    LEFT JOIN tbl_contacts AS o ON a.id = o.contactId 
    LEFT JOIN tbl_invites AS i ON a.id = i.invitedId 
GROUP BY a.id, a.username

【讨论】:

    【解决方案2】:

    如您在此manual page 中所见,有多种方法可以获得分组最大值/最小值。

    最适合你的是第一个,如果行的顺序不能按字母顺序定义

    在这种情况下,如果所需的顺序是 z-a-m(请参阅 Rams 的评论),您将需要 FIELD() 函数。

    所以你的答案是

    SELECT 
    a.id, 
    a.userName,
    if(o.userId=1,'C',if(i.userId=1,'I','N')) AS relation 
    FROM tbl_users a
    LEFT JOIN tbl_contacts AS o ON a.id = o.contactId 
    LEFT JOIN tbl_invites AS i ON a.id = i.invitedId 
    WHERE 
    if(o.userId=1,'C',if(i.userId=1,'I','N')) = (
        SELECT 
        if(o.userId=1,'C',if(i.userId=1,'I','N')) AS relation 
        FROM tbl_users aa
        LEFT JOIN tbl_contacts AS o ON aa.id = o.contactId 
        LEFT JOIN tbl_invites AS i ON aa.id = i.invitedId 
        WHERE aa.id = a.id AND aa.userName = a.userName
        ORDER BY FIELD(relation, 'N', 'I', 'C') DESC 
        LIMIT 1
    )
    

    请注意,您也可以像 ORDER BY FIELD(relation, 'C', 'I', 'N') 一样进行操作,使其更具可读性/直观性。我把它反过来了,因为如果你有可能在关系中有一个“X”,FIELD()函数会返回0,因为X没有被指定为参数。因此它将在“C”之前排序。通过降序排序和翻转参数的顺序是不可能发生的。

    【讨论】:

    • 这个查询不会花费很多时间吗?它有“4 个左连接”!!
    • 这不一定是坏事。这取决于您是否创建了具有正确索引的表。如果你有这个查询不会有任何麻烦。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    相关资源
    最近更新 更多