簡體   English   中英

Postgres中的優先選擇語句

[英]Priority select statement in Postgres

我有Rails應用程序。 在此應用程序中,我將模塊globalize3用於i18n。 我有帶有此行的localedescriptiontitle表格newsnews_translations 我使用join語句獲取所有新聞檢查當前區域設置。 對於當前語言環境,這是正確的工作。 例如:

WHERE "news_tranlations"."locale" = 'it'

但我想提出另一種邏輯。 例如,如果來自'de'用戶,我向他顯示所有帶有語言環境'de'新聞,以及所有沒有'de'翻譯但帶有'en' 當我嘗試使用OR語句執行此操作時,我得到兩個翻譯為'de''en' 我是否可以使用優先級之類的東西來糾正問題。

這是一個尷尬的查詢。 簡而言之,您需要對可能的行進行“或”運算,然后計算case when locale = 'it' then 1 when ... endcase 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生成的表)上沒有索引。

SQL小提琴

您可以使用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.

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