簡體   English   中英

使用postgres在帶軌道的DISTINCT ID中訂購

[英]Order with DISTINCT ids in rails with postgres

我有以下代碼用micropost_id列連接兩個表微博和活動,然后根據具有不同微博id的活動表的created_at進行排序。

 Micropost.joins("INNER JOIN activities ON 
 (activities.micropost_id = microposts.id)").
 where('activities.user_id= ?',id).order('activities.created_at DESC').
 select("DISTINCT (microposts.id), *")

這應該返回整個微柱。這在我的開發環境中不起作用。

(PG::InvalidColumnReference: ERROR:  for SELECT DISTINCT, ORDER BY expressions must appear in select list

如果我在SELECT DISTINCT中添加activities.created_at,我會得到重復的微博ID,因為它有不同的activities.created_at列。 我已經做了很多搜索到達這里。 但是由於這種postgres條件,問題總是存在,以避免隨機選擇。

我想根據activities.created_at的順序選擇不同的micropost _id。

請幫忙..

首先,我們需要快速介紹SELECT DISTINCT實際執行的操作。 看起來只是一個很好的關鍵字,以確保您只返回不同的值,這不應該改變任何東西,對嗎? 除了你在幕后發現, SELECT DISTINCT實際上更像是一個GROUP BY 如果要選擇某些事物的不同值,則只能按照您選擇的相同值對該結果集進行排序 - 否則,Postgres不知道該怎么做。

要解釋模糊性的來源,請考慮您的activities這一組簡單數據:

CREATE TABLE activities (
  id INTEGER PRIMARY KEY,
  created_at TIMESTAMP WITH TIME ZONE,
  micropost_id INTEGER REFERENCES microposts(id)
);
INSERT INTO activities (id, created_at, micropost_id)
VALUES (1, current_timestamp,                      1),
       (2, current_timestamp - interval '3 hours', 1),
       (3, current_timestamp - interval '2 hours', 2)

您在問題中聲明要根據activities.created_at的順序“distinct micropost_id”。 這很容易通過降created_at(訂購這些活動的1, 3, 2 ),但兩者12有1相同micropost_id所以,如果你想查詢返回只是微柱的ID,它應該返回1, 22, 1

如果您可以回答上述問題,則需要采用您的邏輯並將其移至查詢中。 讓我們說,我認為這很可能,你希望這是一個最近作用的微博列表。 在這種情況下,您希望按最近活動的降序對微博進行排序。 Postgres可以通過多種方式為您做到這一點,但最簡單的方法是:

SELECT micropost_id
FROM activities
JOIN microposts ON activities.micropost_id = microposts.id
GROUP BY micropost_id
ORDER BY MAX(activities.created_at) DESC

請注意,我已經刪除了SELECT DISTINCT位,轉而使用GROUP BY ,因為Postgres會更好地處理它們。 MAX(activities.created_at)位告訴Postgres,對於具有相同micropost_id的每組活動,僅按最近的排序。

您可以將上述內容翻譯為Rails,如下所示:

Micropost.select('microposts.*')
  .joins("JOIN activities ON activities.micropost_id = microposts.id")
  .where('activities.user_id' => id)
  .group('microposts.id')
  .order('MAX(activities.created_at) DESC')

希望這可以幫助! 如果您想了解有關查詢如何工作的更多信息,可以使用此sqlFiddle

請嘗試以下代碼

Micropost.select('microposts.*, activities.created_at')
.joins("INNER JOIN activities ON (activities.micropost_id = microposts.id)")
.where('activities.user_id= ?',id)
.order('activities.created_at DESC')
.uniq

暫無
暫無

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

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