我需要在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);
我如何才能查看每个专业的薪水最高的医生。
答案 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;
查询使用CTE和RANK() 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而不是内联视图可以使查询更具可读性,并允许查询优化器提高性能(通常)。它们真的很容易学习。