2016-09-22 79 views
0

我創建了一個有3列的視圖:service_id,professional_id和avg(評級),這個視圖工作正常。分組和分組功能?

CREATE VIEW nota_profissionais 
AS 
    SELECT 
     service_id, professional_id, avg(nota) AS nota_media 
    FROM 
     avaliacao, servico_executado, solicitacao 
    WHERE 
     avaliacao.service_id = servico_executado.id 
     AND servico_executado.id_solicitacao = solicitacao.id 
    GROUP BY 
     service_id, professional_id; 

現在,每個service_id返回(每種類型的服務),我需要證明它具有最佳的平均等級的專業。我試着這樣做:

SELECT 
    service_id, professional_id, MAX(nota_media) AS nota_media 
FROM 
    nota_profissionais 
GROUP BY 
    service_id, professional_id; 

但它從視圖返回同樣的事情,顯示出每service_id爲每professional_id。我知道爲什麼發生這種情況,但不知道如何正確執行此查詢。對不起,如果我不清楚,因爲英語不是我的母語。

+3

今天提示:切換到現代,明確的'JOIN'語法!更容易編寫(沒有錯誤),更易於閱讀,並且更容易轉換爲外連接(如果需要)。 – jarlh

回答

0

您可以用LATERAL子查詢做到這一點:

SELECT * 
FROM 
    (SELECT DISTINCT service_id FROM nota_profissionais) t1, 
    LATERAL (SELECT professional_id, nota_media 
      FROM nota_profissionais 
      WHERE service_id=t1.service_id 
      ORDER BY nota_media DESC LIMIT 1) t2 

這會發現所有不同service_id S(第一子查詢),然後爲他們每個人,它會找到一個最好的專業(第二子查詢,與LATERAL)。

如果您有大量數據,請確保您有(service_id, nota_media DESC)的索引。

+0

不要求橫向連接必須「重新運行」FROM中每個項目的查詢?看起來像這樣會比窗口解決方案慢得多,但我沒有一個DB來測試。非常可愛的技巧壽。 – Hogan

+0

感謝aswer,它做到了。我會查找橫向連接的文檔。 –

+0

@ S.Costa我忘記了一個條件,現在可以重試嗎? – redneb

1

您可以使用窗口函數來做到這一點:

SELECT service_id, professional_id, nota_media, 
FROM (
    SELECT service_id, professional_id, nota_media, 
     ROW_NUMBER() OVER (PARTITION BY service_id ORDER BY nota_media DESC) as RN 
) x 
WHERE RN = 1 
+0

感謝您的幫助 –

0

我認爲最好的辦法是DISTINCT ON

SELECT DISTINCT ON (service_id) np.* 
FROM nota_profissionais np 
ORDER BY service_id, nota_media DESC; 

不僅是在查詢長度最短,但DISTINCT ON往往具有更好的性能與其他方法相比。

0

如果有幾個專業人士相同的最好的評價,你想所有的人,不僅是第一個隨機:

select t.* 
from nota_profissionais t 
    join (
    select service_id, max(nota_media) as nota_media 
    from nota_profissionais 
    group by service_id) t1 
    on (t.service_id = t1.service_id and t.nota_media = t1.nota_media) 

其實同樣的結果應該返回@ Hogan的答案,如果改變ROW_NUMBER()RANK()函數。