创建视图,选择与另一列相关的一列中的最大值
create view selecting the max in one column related with another column
我需要在 PostgreSQL 9.4 中为此创建一个视图 table:
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)
);
该视图将显示每个 specialty
最高 salary
的医生的排名,我试过这段代码,但它显示了每个专业的所有医生:
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);
视图只显示每个专业薪水最高的医生,我该怎么办。
这是一个按薪水显示每个专业的最佳医生的查询:
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 and the RANK() window function 来完成这项工作。如果您以前没有使用过它们,您可能想阅读它们的文档。
DISTINCT ON
是一种简单的 Postgres 特定技术,可让每个组获得 一个 获胜者。详情:
- Select first row in each GROUP BY group?
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
:
- PostgreSQL sort by datetime asc, null first?
对于大表和某些数据分布,其他查询技术更胜一筹:
- Optimize GROUP BY query to retrieve latest record per user
不使用通用 Table 表达式或分析,您可以使用内联 view/virtual table:
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 而不是内联视图使查询更具可读性并允许查询优化器产生更好的性能(通常)。它们真的很容易学。
我需要在 PostgreSQL 9.4 中为此创建一个视图 table:
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)
);
该视图将显示每个 specialty
最高 salary
的医生的排名,我试过这段代码,但它显示了每个专业的所有医生:
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);
视图只显示每个专业薪水最高的医生,我该怎么办。
这是一个按薪水显示每个专业的最佳医生的查询:
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 and the RANK() window function 来完成这项工作。如果您以前没有使用过它们,您可能想阅读它们的文档。
DISTINCT ON
是一种简单的 Postgres 特定技术,可让每个组获得 一个 获胜者。详情:
- Select first row in each GROUP BY group?
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
:
- PostgreSQL sort by datetime asc, null first?
对于大表和某些数据分布,其他查询技术更胜一筹:
- Optimize GROUP BY query to retrieve latest record per user
不使用通用 Table 表达式或分析,您可以使用内联 view/virtual table:
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 而不是内联视图使查询更具可读性并允许查询优化器产生更好的性能(通常)。它们真的很容易学。