分组和分组功能?

时间:2016-09-22 20:46:56

标签: sql postgresql

我创建了一个包含3列的视图:service_id,professional_id和avg(rating),此视图工作正常。

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。我知道为什么会这样,但不知道如何正确地执行此查询。对不起,如果我不清楚,因为英语不是我的母语。

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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)上有索引。

答案 2 :(得分:0)

我认为最好的方法是DISTINCT ON

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

查询长度不仅最短,而且DISTINCT ON与其他方法相比通常具有更好的性能。

答案 3 :(得分: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)

如果将ROW_NUMBER()更改为RANK()函数,实际上相同的结果应返回@Hogan的答案。