![](/img/trans.png)
[英]Wilson Score in Rails + Add Random Number to Upvote in Postgres Select Statement
[英]Priority select statement in Postgres
我有Rails應用程序。 在此應用程序中,我將模塊globalize3用於i18n。 我有帶有此行的locale
, description
和title
表格news
和news_translations
。 我使用join語句獲取所有新聞檢查當前區域設置。 對於當前語言環境,這是正確的工作。 例如:
WHERE "news_tranlations"."locale" = 'it'
但我想提出另一種邏輯。 例如,如果來自'de'
用戶,我向他顯示所有帶有語言環境'de'
新聞,以及所有沒有'de'
翻譯但帶有'en'
。 當我嘗試使用OR
語句執行此操作時,我得到兩個翻譯為'de'
和'en'
。 我是否可以使用優先級之類的東西來糾正問題。
這是一個尷尬的查詢。 簡而言之,您需要對可能的行進行“或”運算,然后計算case when locale = 'it' then 1 when ... end
按case when locale = 'it' then 1 when ... end
排序的子結果集的頂行, case when locale = 'it' then 1 when ... end
排序。 有很多方法可以得出正確的結果(尤其是窗口函數),但是坦率地說,出於性能方面的考慮,您真的不想去那里。
Methinks重新審視您的假設,或更改您的架構。
使它相當快的一種方法是將數組列添加到由觸發器維護的新聞項(例如languages
)中。 使用該新聞過濾熱門新聞(我認為這是您要獲取的新聞),而不是針對翻譯進行聯接。 (注意:根據您的Postgres版本,請避免在該列上添加GIST索引,因為&&
運算符的選擇性是硬編碼的,並且會使用超出特定行的btree超過/ by / limit / offset的順序。)
使其變得相當快的另一種方法是跟蹤每種語言的單獨的供稿表-基本上是一個物化視圖,該視圖產生您要構建的查詢的ID。
如您所見,這兩種選擇都等於部分或完全預先計算了每種語言所顯示的行。 根據我自己的經驗,使用數組列的第一種方法可以很好地工作-我喜歡將其用於標簽,加快和/或過濾。
認真考慮Denis關於性能和更改架構的評論。 但是,以下內容確實可以解決您的問題,並且如果您不讓weighted_tables變得太大,則可能適用。 請特別注意,公用表表達式(表WITH生成的表)上沒有索引。
您可以使用DISTINCT和ORDER BY來欺騙它。
我不知道您的新聞主鍵和外鍵是什么,但是假設它是“ news_id”,則可以這樣操作:
SELECT
DISTINCT ON (n.news_id),
n.news_id,
nt.title,
nt.description
FROM
news n INNER JOIN news_translation nt
ON
n.news_id = nt.news_id
ORDER BY
n.news_id,
nt.locale != 'de',
nt.locale != 'en',
nt.locale;
該查詢將始終向您返回新聞文章一次(沒有重復和多次翻譯),並且最好為您提供“ de”翻譯(如果存在),如果不存在,它將歸為“ en”,如果兩者均不包含存在,它將為您提供按“語言環境”排序的第一個翻譯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.