V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Macv1994
V2EX  ›  程序员

一个 MySQL 查询问题

  •  
  •   Macv1994 ·
    weijiang1994 · 176 天前 via Android · 955 次点击
    这是一个创建于 176 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有一张私信表表结构如下图

    1637548753322.png

    我想把当前用户的所有私信查询出来,我现在使用的下面的查询语句

    # 假设当前用户 id 为 12
    select * from t_message where receiver_id == 12 group by sender_id;
    

    但是这样有两个问题

    1. 如果是 12 用户给其他用户发送的私信,如果对方没有回复的话,那么就查询不出来。
    2. MySQL5.7 以后默认开启了ONLY_FULL_GROUP_BY,用上面的查询语句会报错,要关掉才可以。

    请求各位大佬,怎么解决小弟这个问题?

    17 条回复    2021-11-24 09:29:33 +08:00
    onhao
        1
    onhao  
       176 天前
    mysql8 only_full_group_by 的解决办法 https://wuhao.pw/archives/179/
    onhao
        2
    onhao  
       176 天前
    @Macv1994 "如果是 12 用户给其他用户发送的私信,如果对方没有回复的话" 那么 sender_id 是 12 ?
    mysql 好像 receiver_id = 12 这样 就行吧 不需要==
    可能是我理解的问题, 这样不知可否
    select * from t_message where receiver_id = 12 or sender_id=12 group by sender_id;
    cdcdc
        3
    cdcdc  
       176 天前
    如果只是为了去重,就用 select xxx, DISTINCT sender_id WHERE receiver_id = 12
    Macv1994
        4
    Macv1994  
    OP
       175 天前
    @onhao ONLY_FULL_GROUP_BY 通过查看文档可以通过 ANY_VALUE 来解决。
    onhao
        5
    onhao  
       175 天前
    @Macv1994 确实,采用 any_value() 似乎更加好。
    只是你的问题,最终怎么解决的?
    qianProgrammer
        6
    qianProgrammer  
       175 天前
    select * from t_message where receiver_id = 12
    UNION
    select * from t_message where sender_id = 12
    mitsuizzz
        7
    mitsuizzz  
       175 天前
    发送人或者接收人 id 为 12 不就都查出来了,我理解一行对应一条私信,查出所有私信为什么还要分组
    lybcyd
        8
    lybcyd  
       175 天前
    为什么需要 group by ,一个发送人只显示一条吗?能明确一下规则么
    Macv1994
        9
    Macv1994  
    OP
       175 天前 via Android
    @mitsuizzz
    @lybcyd 我没有表述清楚,因为我要做一个类似微信聊天左侧侧边栏的效果 不知道是不是我想复杂了 https://2dogz.cn/backend/files/5076image.png
    Macv1994
        10
    Macv1994  
    OP
       175 天前 via Android
    @onhao 我最后分开两个 SQL 进行 group by😂
    DefineJ
        11
    DefineJ  
       175 天前
    我今天刚把聊天记录和列表拆分出来,列表只记录最后一次聊天
    lybcyd
        13
    lybcyd  
       175 天前 via Android
    @Macv1994 那按照业务逻辑应该是需要时间倒序的,group by 排序我记得是没有保证的,查询非 group by 和非聚合字段也不符合 SQL 标准。
    如果用的 MySQL8 可以用开窗函数,如果是 5.7 那就子查询按照对话双方来分组查询最新时间。
    因为这里是对话,应该需要按照 receiver 和 sender 两个字段分组吧。
    MidGap
        14
    MidGap  
       175 天前
    @Macv1994 用 zset 维护个联系人列表似乎可以,score 是最后一次消息的时间,排序也省了
    Macv1994
        15
    Macv1994  
    OP
       174 天前
    @lybcyd 嗯是的,group by 可以通过 any_value 来解决,我现在是分开查询的,先把根据 sender_id 分组条件为 receiver_id=12 ,然后将条件设置为 sender_id=12 and receiver_id not in [group by sender_id]
    Macv1994
        16
    Macv1994  
    OP
       174 天前
    @DefineJ 感谢,我看一下。
    Macv1994
        17
    Macv1994  
    OP
       174 天前
    @MidGap 你是说用 redis 的 zset 吗?
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1180 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 19:53 · PVG 03:53 · LAX 12:53 · JFK 15:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.