Postgresql SQL查询,以确定一个表是否具有比另一个表更多的属性行
我的家庭作业练习有问题,如下所示: Table "university.prof" Column | Type | Modifiers -----------+-----------------------+----------- pnum | character(9) | not null lastname | character varying(12) | not null firstname | character varying(12) | dept | character(4) | office | character(6) | rank | character(1) | date_emp | date | not null salary | numeric(8,2) | manager | character(9) | Indexes: "prof_pkey" PRIMARY KEY, btree (pnum) Table "university.student" Column | Type | Modifiers -----------+---------------+----------- snum | character(9) | not null lastname | character(12) | firstname | character(12) | dept | character(4) | date_ent | date | cr_comp | smallint | gpa | numeric(4,3) | advisor | character(9) | Indexes: "student_pkey" PRIMARY KEY, btree (snum) SET search_path TO university; SELECT prof.dept FROM prof, student WHERE prof.dept = student.dept GROUP BY prof.dept HAVING count(DISTINCT prof.*) > count(DISTINCT student.*); 找到教授多于学生的所有系 所涉及的表格如下: Table "university.prof" Column | Type | Modifiers -----------+-----------------------+----------- pnum | character(9) | not null lastname | character varying(12) | not null firstname | character varying(12) | dept | character(4) | office | character(6) | rank | character(1) | date_emp | date | not null salary | numeric(8,2) | manager | character(9) | Indexes: "prof_pkey" PRIMARY KEY, btree (pnum) Table "university.student" Column | Type | Modifiers -----------+---------------+----------- snum | character(9) | not null lastname | character(12) | firstname | character(12) | dept | character(4) | date_ent | date | cr_comp | smallint | gpa | numeric(4,3) | advisor | character(9) | Indexes: "student_pkey" PRIMARY KEY, btree (snum) SET search_path TO university; SELECT prof.dept FROM prof, student WHERE prof.dept = student.dept GROUP BY prof.dept HAVING count(DISTINCT prof.*) > count(DISTINCT student.*); 这个问题本质上要求提供一个值列表,其中左表的值行比右表的多。我该怎么做?此查询不起作用: SET search_path TO university; SELECT dept FROM prof GROUP BY dept HAVING count(*) > ( SELECT count(*) FROM student GROUP BY dept ); 导致以下错误: ERROR: more than one row returned by a subquery used as an expressionPostgresql SQL查询,以确定一个表是否具有比另一个表更多的属性行,postgresql,join,group-by,aggregate-functions,Postgresql,Join,Group By,Aggregate Functions,我的家庭作业练习有问题,如下所示: Table "university.prof" Column | Type | Modifiers -----------+-----------------------+----------- pnum | character(9) | not null lastname | character varying(12) | not null firstname | characte
SELECT dept
FROM prof
GROUP BY dept
HAVING count(*) > (
SELECT count(*) /* This subquery would yield rows equal to no of different
FROM student Department to which students belong.
GROUP BY dept Thus you can't compare it with > symbol.*/
);
此代码也不起作用,导致没有返回行。正确答案返回两行:
SET search_path TO university;
SELECT prof.dept
FROM prof, student
GROUP BY prof.dept
HAVING count(prof.*) > count(student.*);
我该怎么做?我不是在寻找完整的答案,而是关于如何构造查询的提示。我正在Windows 7上使用PostgreSQL 9.1.3
编辑:谢谢你的帮助。正确答案如下:
Table "university.prof"
Column | Type | Modifiers
-----------+-----------------------+-----------
pnum | character(9) | not null
lastname | character varying(12) | not null
firstname | character varying(12) |
dept | character(4) |
office | character(6) |
rank | character(1) |
date_emp | date | not null
salary | numeric(8,2) |
manager | character(9) |
Indexes:
"prof_pkey" PRIMARY KEY, btree (pnum)
Table "university.student"
Column | Type | Modifiers
-----------+---------------+-----------
snum | character(9) | not null
lastname | character(12) |
firstname | character(12) |
dept | character(4) |
date_ent | date |
cr_comp | smallint |
gpa | numeric(4,3) |
advisor | character(9) |
Indexes:
"student_pkey" PRIMARY KEY, btree (snum)
SET search_path TO university;
SELECT prof.dept
FROM prof, student
WHERE prof.dept = student.dept
GROUP BY prof.dept
HAVING count(DISTINCT prof.*) > count(DISTINCT student.*);
编辑2:有更好的解决方案。我已接受包含此解决方案的答案。您第一次查询中导致错误的部分: ERROR: more than one row returned by a subquery used as an expression
SELECT dept
FROM prof
GROUP BY dept
HAVING count(*) > (
SELECT count(*) /* This subquery would yield rows equal to no of different
FROM student Department to which students belong.
GROUP BY dept Thus you can't compare it with > symbol.*/
);
相反,您必须遍历选择的教授表,并为每个教授计算该系的教授人数,然后相应地找到与上述教授属于同一系的学生。
大概是这样的:
select t.prof from prof t where
(
select count(*) from prof where dept=t.dept
)
>
(
select count(*) from student where dept=t.dept
)
找到教授多于学生的所有系
考虑一下这一点:
SELECT p.dept, p.prof_ct, s.stud_ct
FROM (
SELECT dept, count(*) AS prof_ct
FROM university.prof
GROUP BY dept
) p
LEFT JOIN (
SELECT dept, count(*) AS stud_ct
FROM university.student
GROUP BY dept
) s USING (dept)
WHERE p.prof_ct >= s.stud_ct OR s.stud_ct IS NULL
ORDER BY p.dept;
应该比你现在的解决方案快得多,因为学生和教授在数量级联接之前就被计算出来了
它还观察到一个系没有学生的情况,而您的解决方案目前忽略了这一点。交叉联接消除了所有没有学生或教授的系。另一种解决方案使用视图: 根据需要创建或替换临时视图p 选择dept,count*num 来自教授 按部门分组 ; 根据需要创建或替换临时视图 选择dept,count*num 来自学生 按部门分组 ; 选择不同的p.dept 从p,s 其中p.num>s.num;
此代码正确处理给定部门没有教授或学生的情况。使用have count*>是最可能的错误原因。第二次尝试将错过一个连接谓词,该谓词按部门连接两个表,其中prof.dept=student.dept和关键字在两个计数中都是不同的,因为这样它会计数教授和学生的重复,总是一样的。