簡體   English   中英

如何在 mysql 的 group by 子句中最后創建 select 記錄?

[英]How to select last created record in a group by clause in mysql?

我正在使用mysql 8.0.23

我有三個表, chatschat_userschat_messages

我想要 select chat_id,最后一條消息(具有特定組的最大 createdAt 日期。換句話說,組內 created_at desc 的消息順序),來自 id 1 的用戶是成員的所有聊天的 from_user_id 值.

表 sql 和 DDL 如下所示

create table chats
(
    id         int unsigned auto_increment primary key,
    created_at timestamp default CURRENT_TIMESTAMP not null
);

create table if not exists chat_users
(
    id      int unsigned auto_increment
        primary key,
    chat_id    int unsigned not null,
    user_id int unsigned not null,
    constraint chat_users_user_id_chat_id_unique
        unique (user_id, chat_id),
    constraint chat_users_chat_id_foreign
        foreign key (chat_id) references chats (id)
);

create index chat_users_chat_id_index
    on chat_users (chat_id);

create index chat_users_user_id_index
    on chat_users (user_id);


create table chat_messages
(
    id       int unsigned auto_increment primary key,
    chat_id  int unsigned                            not null,
    from_user_id int unsigned                            not null,
    content      varchar(500) collate utf8mb4_unicode_ci not null,
    created_at   timestamp default CURRENT_TIMESTAMP     not null    constraint chat_messages_chat_id_foreign
        foreign key (chat_id) references chats (id),
);

create index chat_messages_chat_id_index
    on chat_messages (chat_id);
    
create index chat_messages_from_user_id_index
    on chat_messages (from_user_id);

到目前為止我嘗試過但無法正常工作的查詢是


SET @userId = 1;
select
       c.id as chat_id,
       content,
       chm.from_user_id
from chat_users
         inner join chats c on chat_users.chat_id = c.id
         inner join chat_messages chm on c.id = chm.chat_id
where chat_users.user_id = @userId
group by c.id
order by c.id desc, max(chm.created_at) desc

我上面的查詢沒有返回最后創建的消息的content字段,盡管我試圖按 max(chm.created_at) desc 排序。 這個 order by after group by 子句是在我認為的分組之后執行的,而不是在組中的項目中執行的。我知道我可以在 select 聲明最大日期中的 select,但我想要 select 組中的最后一個內容值不是select max(ch.created_at) 作為 last_created_at_msg_within_group

我不知道如何通過與 c.id 分組來 select 組中具有最高 chm.created_at 的項目的content字段

示例測試數據

chats

1 2021-07-23 20:51:01
2 2021-07-23 20:51:01
3 2021-07-23 20:51:01

chats_users

1 1 1
2 1 2
3 2 1 
4 2 2
5 3 1
6 3 2

chat_messages

1 1 1 lastmsg 2021-07-28 21:50:31
1 1 2 themsg  2021-07-23 20:51:01

這種情況下的邏輯應該返回

chat_id  content   from_user_id
1        lastmsg   1

PS:在這里發帖之前,我做了功課並研究了論壇中的類似問題,但他們試圖從一組中獲取最后插入的行,而不是像我的那樣。

這是我想出的,用於 MySQL 8.0 和 window 函數的解決方案:

select * from (
  select
      c.id as chat_id,
      content,
      chm.from_user_id,
      chm.created_at,
      row_number() over (partition by c.id order by chm.created_at desc) as rownum
  from chat_users
      inner join chats c on chat_users.chat_id = c.id
      inner join chat_messages chm on c.id = chm.chat_id
  where chat_users.user_id = @userId
) as t
where rownum = 1;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM