MySQL group by 左连接

Posted

技术标签:

【中文标题】MySQL group by 左连接【英文标题】:MySQL group by with left join 【发布时间】:2019-01-15 21:45:04 【问题描述】:

我正在尝试做一个非常复杂的查询(至少对我来说非常复杂,对你来说不是:))

我有用户和 cmets 表。

SQL 小提琴:http://sqlfiddle.com/#!9/b1f845/2

select user_id, status_id from comments where user_id in (2,3);
+---------+-----------+
| user_id | status_id |
+---------+-----------+
|       2 |        10 |
|       2 |        10 |
|       2 |        10 |
|       2 |         7 |
|       2 |         7 |
|       2 |        10 |
|       3 |         9 |
|       2 |         9 |
|       2 |         6 |
+---------+-----------+

如果我使用

select user_id, status_id from comments where user_id in (2,3)

它返回很多重复值。

如果可能的话,我想得到什么。

如果你看到status_id = 10user_id= 2,3 and 4 and 2 multiple times. 所以从这里我想获得最大的最新user_id(唯一),例如,

这将是 user_id = 4 and 2 现在主要的复杂部分。我现在想在一列中获取user_id= 4 and 2 的用户信息,以便最后我可以得到这样的东西

status_id |  userOneUserName | userTwoUserName
 10            sadek4             iamsadek2
 ---------------------------------------------
 7        |    iamsadek2     |      null
 ---------------------------------------------
 9 .      |    iamsadek2     |      sadek2
 ---------------------------------------------
 6        |    iamsadek2     |       null

我怎样才能实现这么复杂的事情。 目前我必须使用应用程序逻辑来做到这一点。

感谢您的宝贵时间。

【问题讨论】:

你用的是什么版本的 mysql 感谢您的快速回复。运行 mysql --version 我得到mysql Ver 14.14 Distrib 5.7.21, for osx10.13 (x86_64) using EditLine wrapper 这个数据集中没有用户4 【参考方案1】:

我认为这可能是您真正想要的:

SELECT DISTINCT
    status_id,
    (SELECT MAX(user_id) FROM comments c2 WHERE c1.status_id = c2.status_id) user_1,
    (SELECT user_id FROM comments c2 WHERE c1.status_id = c2.status_id
     ORDER BY user_id LIMIT 1 OFFSET 1) user_2
FROM comments c1
WHERE user_id IN (2,3);

Demo

(你的更新小提琴)

我们可以使用相关子查询来找到每个status_id 的最大user_id 和第二最大user_id,然后将它们中的每一个旋转为两个单独的列。在这里使用GROUP_CONCAT 方法可能更可取,因为它还可以让您轻松地以 CSV 列表的形式容纳任意数量的用户。

此外,如果您使用的是 MySQL 8+ 或更高版本,那么我们可以利用排名分析函数,这也更容易。

【讨论】:

简直太棒了。但是无论如何我们可以从 users 表而不是 ids 返回用户详细信息? 是的,我们可以。一种方法是将我的查询包装为子查询,然后将两个用户列中的每一个(读取:连接两次)连接到其他表,以基于user_id 引入另一个值。 如果您可以使用其他表格更新您的 Fiddle,我可以在此处粘贴另一个演示链接。 @sadek 看看this updated demo,它使用我上面给出的查询作为起点,引入了每个用户的名字和姓氏。 @sadek 然后使用左连接将我的查询连接到用户表have a look here。您可以使用COALESCENULL 替换为某个占位符值。或者,您可以保持原样。【参考方案2】:
select status_id, GROUP_CONCAT(distinct(user_id) SEPARATOR ',')
from comments
group by status_id

【讨论】:

很好,它显示了结果,但我如何从2,7 获取用户信息。有可能吗? 只需在 (2,7) 中添加一个 WHERE user_id 你能给我举个例子吗?非常感谢:) select status_id, GROUP_CONCAT(distinct(user_id) SEPARATOR ',') from cmets where user_id in (2,7) group by status_id【参考方案3】:

我建议使用GROUP BYGROUP_CONCAT,例如像这样:

SELECT status_id, GROUP_CONCAT(userName) AS users, GROUP_CONCAT(DISTINCT c.user_id) AS user_ids 
FROM (
  SELECT DISTINCT status_id, user_id FROM comments WHERE user_id in (2,3)
) c
JOIN users u ON (c.user_id = u.id)
GROUP BY status_id
ORDER BY status_id DESC

【讨论】:

这个答案更棒了。 :) 你能给我一些关于这种高级 SQL 学习的学习资料吗?非常感谢, 很难说 :) 我喜欢阅读有关 mysql 的性能博客,例如 percona.com/blog,我的大部分知识实际上来自阅读堆栈溢出和数据库堆栈交换。还有官方资源其实也挺好的,比如mariadb.com/kb/en/library/select或者dev.mysql.com/doc/refman/5.7/en/select.html 发表了一个问题***.com/questions/51799475/… 。请如果你有时间。谢谢

以上是关于MySQL group by 左连接的主要内容,如果未能解决你的问题,请参考以下文章

使用左连接连接表时如何正确查询 group by

如何使用 group_concat 和左连接计算 mysql 查询的结果

MYSQL:与 Group_Concatenate 一起使用的两个表上的左连接

MySQL使用多个左连接获取重复项

MySQL调优--05---多表查询优化子查询优化 ORDER BY优化GROUP BY优化分页查询优化

SQL左连接和group_concat返回重复数据