簡體   English   中英

如何根據組和順序查詢記錄?

[英]How to query for records based on a group and ordering?

給定以下模型:

User
    id
UserPulses
    id, user_id, group_id, created_at

我想做的是獲取按(group_id)分組的所有用戶UserPulses,並且僅按group_id獲取最新的UserPulse。 我已經能夠通過逐組循環來做到這一點,但這需要大量的查詢。 一個查詢可能嗎?

類似於:user.user_pulses.group(“ group_id)”)

有任何想法嗎? 謝謝

您無法通過常規的ActiveRecord接口可靠地完成此操作,但您可以使用窗口函數通過SQL進行操作。 您想要一些這樣的SQL:

select id, user_id, group_id, created_at
from (
    select id, user_id, group_id, created_at, 
           row_number() over (partition by group_id order by created_at desc, id desc) as r
    from user_pulses
    where user_id = :user_id
) dt
where r = 1

然后將其包裝在find_by_sql

pulses = UserPulses.find_by_sql([%q{
    select id, user_id, group_id, created_at
    from (
        select id, user_id, group_id, created_at, 
               row_number() over (partition by group_id order by created_at desc, id desc) as r
        from user_pulses
        where user_id = :user_id
    ) dt
    where r = 1
}, :user_id => user.id])

窗口函數部分實質上是對每個group_id進行本地GROUP BY,對它們group_id排序(將id desc作為輔助排序鍵作為“以防萬一”的平局決勝者),並在r每個組的行號。 然后外部查詢過濾掉每個組中的第一個查詢( where r = 1 ), and peels off the original user_pulses`列。

您可以使用SQL功能DISTINCT的PostgreSQL特定擴展: DISTINCT ON

SELECT DISTINCT ON (group_id)
       id, user_id, group_id, created_at
FROM   user_pulses
WHERE  user_id = :user_id
ORDER  BY group_id, created_at DESC, id; -- id just to break ties

比窗口函數更簡單(但不那么可移植),並且可能最快。
有關此問題的更多詳細信息

大概是這樣的。 但是,如果一個用戶/ group_id組合具有相同的日期,則可能會有多個記錄。

SELECT p.id, p.user_id, p.group_id, p.created_at
  FROM UserPulses p
      ,( SELECT user_id, group_id, MAX(created_at) as max_date
           FROM UserPulses
           GROUP BY user_id, group_id ) m
  WHERE u.user_id = m.user_id
    AND u.group_id = m.group_id
    AND u.created_at = m.max_date

暫無
暫無

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

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