有个需求不知道怎么写 SQL,特来请教一下

2019-12-11 10:36:28 +08:00
 reidxx

如图表结构,现在需要根据 space_id&user_id 做 group by,然后查询 create_at 最大的那条数据,被难倒了,有没有大佬赐教一下。

6278 次点击
所在节点    MySQL
35 条回复
surfire91
2019-12-11 11:46:04 +08:00
如果同一 space_id, user_id 下 create_at 最大的有多条,需要返回几条?
如果只需要返回 1 条(譬如 create_at 最大,id 最小的 1 条)的话楼上有些是不满足需求的。
ChoateYao
2019-12-11 11:47:03 +08:00
我在二楼已经回答了这个问题,MySQL 的 Group By 特性就是根据数据默认排序,取去重数据的第一条。

根据这个特性,我们先对数据进行排序,然后在 Group By 即可得到你想要的结果。

但是在 MariaDB 中,该方法并不起效果,需要额外引入一个莫名其妙的语句: LIMIT 18446744073709551615

所以最终的 SQL 是: SELECT ..... ( SELECT .... ORDER BY create_at DESC LIMIT 18446744073709551615) AS a GROUP BY space_id, user_id
reidxx
2019-12-11 12:04:54 +08:00
@ChoateYao #22 还真的是,加上那段 limit 后能查出来,不加 limit 的话,查出来的是 min(create_at) 的数据,能解释下那段 limit 子句是啥意思吗?
reidxx
2019-12-11 12:05:37 +08:00
刚好我司用的是 mariadb..
reidxx
2019-12-11 12:06:53 +08:00
@hiths #5 22 楼大佬的 sql 很简洁,并满足了需求,可参考一下
ChoateYao
2019-12-11 12:10:42 +08:00
x66
2019-12-11 13:45:30 +08:00
mariadb10.2 开始支持开窗函数,如果你用的是 10.2 以后的版本,可以了解一下开窗函数
Seayon
2019-12-11 13:55:42 +08:00
这么看看 oracle 的窗口函数还真是把人养懒了,我只会用窗口函数了
wc951
2019-12-11 14:53:49 +08:00
好巧,这需求我刚做过
select t1.* from table t1,
(select space_id,user_id,max(create_at) as maxtime from table group by space_id,user_id) t2
where t1.space_id=t2.space_id and t1.user_id=t2.user_id and t1.create_at=t2.maxtime
reidxx
2019-12-11 15:27:51 +08:00
@x66 #27 多谢,研究一下
p1094358629
2019-12-11 16:03:35 +08:00
写个子查询啊
Yang857
2019-12-11 16:40:49 +08:00
窗口函数 row_number 解决
levelworm
2019-12-11 22:30:10 +08:00
SELECT
t.*
FROM (
SELECT
t.*,
MAX(create_at) OVER(PARTITION BY space_id, user_id) AS max_create_at
FROM
table AS t
) AS a
INNER JOIN table AS t
ON t.space_id = a.space_id AND t.user_id = a.user_id AND t.create_at = a.max_create_at

或者楼上说的窗口函数更简单
SELECT
t.*
FROM (
SELECT
t.*,
ROW_NUMBER() OVER(PARTITION BY space_id, user_id ORDER BY create_at DESC) AS row_num
FROM
table AS t
) AS a
WHERE
row_num = 1
ricky077
2019-12-11 22:43:32 +08:00
SELECT space_id,user_id
FROM table
GROUP BY space_id,user_id
having created_at = max(created_at)
contmonad
2019-12-12 00:15:59 +08:00
按 SQL 标准本来就不能 select 不属于 group by 的列(在关系代数上没有意义),MySQL 原先支持这种写法只是它的一个扩展,在 v5.7.5 以后 默认开启 ONLY_FULL_GROUP_BY 就不能用了。如果不用窗口函数,这个问题一般是写 self-join 或者使用变量(非声明式)。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/627876

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX