跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 有个需求不知道怎么写 SQL,特来请教一下
未分類
16 6 月 2020

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

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

資深大佬 : reidxx 80

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

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

大佬有話說 (35)

  • 資深大佬 : alpha2016

    SELECT space_id,user_id, max(created_at)
    FROM table
    GROUP BY space_id,user_id

  • 資深大佬 : ChoateYao

    SELECT ….. ( SELECT …. ORDER BY create_at DESC) AS a GROUP BY space_id, user_id

  • 資深大佬 : srx1982

    需求有问题吧

  • 主 資深大佬 : reidxx

    @alpha2016 #1 这样查出来的只是 create_at 字段为最大,其它字段不是同一条记录

  • 資深大佬 : hiths

    SELECT
    t2.*
    FROM
    ( SELECT space_id, user_id, max( create_at ) AS mx FROM TABLE GROUP BY space_id, user_id ) AS t1
    LEFT JOIN TABLE AS t2 ON t2.space_id = t1.space_id
    AND t2.user_id = t1.user_id
    AND t2.create_at = t1.mx

  • 資深大佬 : hiths

    不对,时间能 max ()吗。。。。

  • 資深大佬 : Cooky

    子查询呗

  • 資深大佬 : aragakiyuii

    什么数据库?
    group by 完了 order by create_at desc, 然后取第一条就行了

  • 主 資深大佬 : reidxx

    @hiths #5 多谢老铁,这样可以,我看看能否再简化一些

  • 資深大佬 : hiths

    @reidxx 简化就是写成 where, 不过数据量大就蛋疼了点

  • 資深大佬 : lensan

    select max (created_at) ,space_id,user_id
    from table t
    join (
    space_id,user_id from group by space_id,user_id
    ) t2 on t.space_id=t2.space_id and t.user_id =t2.user_id

  • 資深大佬 : zhesheng

    select * from ( select a.*,row_number() over (partition by a.space_id,a.user_id order by a.create_at desc) rn from table_name a ) where rn =1

  • 主 資深大佬 : reidxx

    @hiths #6 可以的,你上面那条 sql 暂时来看满足需求,我试试增加点数据验证一下。

    @aragakiyuii #8 mysql

  • 資深大佬 : lff0305

    “`
    select * from table as t
    where (select count(distinct(e1.created_at)) from table as t1 where t1.space_id= e.space_id and t1.user_id
    = t.user_id and t1.created_at > t.created_at) < 1;
    “`

    没试验,大概这个意思,效率不高

  • 資深大佬 : andj4cn

    create_at 也需要 group by 吧,先 根据 space_id, user_id, create_at 进行 group by,然后 select * from () order by create_at desc limit 1

  • 主 資深大佬 : reidxx

    @andj4cn #15 每条记录的 create_at 基本都不一样,加入 group by 的话就相当于查全部数据了,再 order by limit 1 就只返回一条数据了

  • 資深大佬 : dofine

    row_number() over (partition by space_id, user_id order by create_at desc)
    == 抱歉忘记好像 mysql 不支持。

  • 資深大佬 : fox0001

    如果是 SQL server,我会用 row_number。具体如下

    select space_id, user_i
    from(
    select space_id, user_id, row_number()over(partition by space_id, user_id order by create_at desc) num
    from …..
    )a
    where number=1

  • 資深大佬 : xuanbg

    如果你的数据只有 space_id、user_id、create_at 的话,1 就能满足你的要求。如果不止这 3 个字段的话,1 的 sql 当做一个子查询,然后用这个结果去 join 原表,on 条件就是这 3 个字段全匹配。

  • 資深大佬 : kiracyan

    这样? 其实没太看懂需求
    select * from t1
    where not exists(select 1 from t2 where t1.user_id=t2.user_id and t1.space_id=t2.space_id and t1.create_at <t2.create_at )

  • 資深大佬 : surfire91

    如果同一 space_id, user_id 下 create_at 最大的有多条,需要返回几条?
    如果只需要返回 1 条(譬如 create_at 最大,id 最小的 1 条)的话上有些是不满足需求的。

  • 資深大佬 : ChoateYao

    我在二已经回答了这个问题,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

    @ChoateYao #22 还真的是,加上那段 limit 后能查出来,不加 limit 的话,查出来的是 min(create_at) 的数据,能解释下那段 limit 子句是啥意思吗?

  • 主 資深大佬 : reidxx

    刚好我司用的是 mariadb..

  • 主 資深大佬 : reidxx

    @hiths #5 22 大佬的 sql 很简洁,并满足了需求,可参考一下

  • 資深大佬 : ChoateYao

    @reidxx https://mariadb.com/kb/en/library/why-is-order-by-in-a-from-subquery-ignored/ 这里有解释

  • 資深大佬 : x66

    mariadb10.2 开始支持开窗函数,如果你用的是 10.2 以后的版本,可以了解一下开窗函数

  • 資深大佬 : Seayon

    这么看看 oracle 的窗口函数还真是把人养懒了,我只会用窗口函数了

  • 資深大佬 : wc951

    好巧,这需求我刚做过
    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

    @x66 #27 多谢,研究一下

  • 資深大佬 : p1094358629

    写个子查询啊

  • 資深大佬 : Yang857

    窗口函数 row_number 解决

  • 資深大佬 : levelworm

    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

    SELECT space_id,user_id
    FROM table
    GROUP BY space_id,user_id
    having created_at = max(created_at)

  • 資深大佬 : contmonad

    按 SQL 标准本来就不能 select 不属于 group by 的列(在关系代数上没有意义),MySQL 原先支持这种写法只是它的一个扩展,在 v5.7.5 以后 默认开启 ONLY_FULL_GROUP_BY 就不能用了。如果不用窗口函数,这个问题一般是写 self-join 或者使用变量(非声明式)。

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具