创建视图,选择与另一列相关的一列中的最大值

时间:2015-04-11 19:35:58

标签: sql postgresql max greatest-n-per-group sql-view

我需要在PostgreSQL 9.4中创建一个关于此表的视图:

CREATE TABLE DOCTOR (
    Doc_Number INTEGER,
    Name    VARCHAR(50) NOT NULL,
    Specialty   VARCHAR(50) NOT NULL,
    Address VARCHAR(50) NOT NULL,
    City    VARCHAR(30) NOT NULL,
    Phone   VARCHAR(10) NOT NULL,
    Salary  DECIMAL(8,2) NOT NULL,
    DNI     VARCHAR(10) NOT NULL,
    CONSTRAINT pk_Doctor PRIMARY KEY (Doc_Number)
  );

该视图将显示每个salary最高specialty的医生的排名,我尝试了此代码,但它显示了每个专业的所有医生:

CREATE VIEW top_specialty_doctors 
AS (Select MAX(Salary), name, specialty from DOCTOR
    where specialty = 'family and community'
    or specialty = 'psychiatry'
    or specialty = 'Rheumatology'
    group by name, salary, specialty);

我如何才能查看每个专业的薪水最高的医生。

3 个答案:

答案 0 :(得分:3)

DISTINCT ON是一种简单的Postgres特定技术,可以为每个群组获得一个获胜者。详细说明:

CREATE VIEW top_specialty_doctors AS 
SELECT DISTINCT ON (specialty)
       salary, name, specialty
FROM   doctor
WHERE  specialty IN ('family and community', 'psychiatry', 'Rheumatology')
ORDER  BY specialty, salary DESC, doc_number  -- as tiebreaker

需要围绕CREATE VIEW查询的括号。

如果多个文档与最高薪水相关联,则选择doc_number最小的文档。

如果salary可以为NULL,请使用DESC NULLS LAST

对于大表和某些数据分布,其他查询技术更优越:

答案 1 :(得分:1)

这是一个查询,显示每个专业的最佳医生薪水:

with specialty_ranks as (
  select 
    Salary, name, specialty,
    rank() over (
      partition by specialty
      order by salary desc
    ) as rank
  from DOCTOR
      where specialty in ('family and community', 'psychiatry', 'Rheumatology')
)
select specialty, name, salary
from specialty_ranks
where rank = 1;

查询使用CTERANK() window function来完成工作。如果您以前没有使用过,可能需要阅读他们的文档。

答案 2 :(得分:0)

不使用公用表表达式或分析,您可以使用内联视图/虚拟表:

Create View top_specialty_doctors as
    Select  m.MaxSalary, d.Name, d.Specialty
    From    Doctor  d
    Join( -- Expose largest salary of each specialty
        Select  Specialty, Max( Salary) as MaxSalary
        From    Doctor
        Group by Specialty
    ) as m
        on  m.Specialty = d.Specialty
        and m.MaxSalary = d.Salary
    Where specialty in( 'family and community', 'psychiatry', 'Rheumatology' );

使用CTE而不是内联视图可以使查询更具可读性,并允许查询优化器提高性能(通常)。它们真的很容易学习。