如何在不使用 JOIN 的情况下使用子查询?



以下问题基于Oracle提供的学生模式数据库:

以下子问题是相关的;在转到下一个子问题之前,请确保您知道如何执行上一个子问题。

(a) 编写 SQL 语句以显示分区 ID 和分区注册。

(b) 编写一个 SQL 语句,在注册学生少于 5 人的部分中列出所有学生(使用格式:,在一列中)。

不要显示任何重复的学生姓名,并按姓氏对结果进行排序。

这些问题将在不使用 JOIN 的情况下回答。请解释如何在没有加入的情况下做到这一点。

表学生列:first_name、last_name、student_id

表注册列:student_id、section_id

对于 2a.,我使用了:

SELECT COUNT(section_id)
FROM enrollment
GROUP BY section_id

这为我提供了每个部分注册的学生数量的正确结果,但是,当我尝试将其用作子查询时:

SELECT last_name, SUBSRT(first_name, 0,1)
FROM student
WHERE ANY(5) < (SELECT COUNT(section_id)
FROM enrollment
GROUP BY section_id)

我收到此错误:

涉及
ORA-00936: missing expression
00936. 00000 -  "missing expression"
Cause:
Action:
Error at Line: 3 Column: 7

表:注册、学生

涉及的注册栏目:student_id、section_id

涉及的学生专栏:student_id、first_name、last_name

这个问题是在假定了解Oracle SQL开发人员提供的学生模式数据库的情况下提出的

我建议使用两个嵌套的子选择。内部是选择注册学生少于 5 人的部分。外部从这些部分中选择student_ids。

SELECT DISTINCT last_name, SUBSTR(first_name, 0, 1)
FROM student
WHERE student_id IN (
SELECT student_id
FROM enrollment
WHERE section_id IN (
SELECT section_id FROM enrollment GROUP BY section_id HAVING COUNT(*) < 5
)
)
ORDER BY lat_name

注意HAVING不像WHERE,是在GROUP BY之后执行的,可以使用聚合函数。

如果所有学生都有不同的姓名,则不需要DISTINCT关键字。如果我们使用 JOIN,这将是必要的,因为这会重复学生行。

我不明白你为什么不想要 JOIN,但你可以做一些事情,用一个子查询并且存在

CREATE TABLe student(student_id int, first_name varchar2(50),last_name varchar2(50))
INSERT INTO student VALUES(1,'A','B')
INSERT INTO student VALUES(2,'C','D')
INSERT INTO student VALUES(3,'E','F')
INSERT INTO student VALUES(4,'G','H')
INSERT INTO student VALUES(5,'I','J')
CREATE tABLe enrollment(student_id int, section_id int)
INSERT INTO  enrollment VALUES (1,1)
INSERT INTO  enrollment VALUES (1,2)
INSERT INTO  enrollment VALUES (1,3)
INSERT INTO  enrollment VALUES (2,2)
INSERT INTO  enrollment VALUES (3,2)
INSERT INTO  enrollment VALUES (4,2)
INSERT INTO  enrollment VALUES (5,2)
SELECT last_name, SUBSTR(first_name, 0,1)
FROM student st

WHERE EXISTS (SELECT 1 FROM enrollment WHERE student_id = st.student_id AND section_id 
IN (  SELECT section_id
FROM enrollment
GROUP BY section_id HAVING COUNT(section_id) < 5))
SUBSTR(FIRST_NAME,0,1)A
LAST_NAME
B

如果我正确关注您,这里不需要嵌套子查询。

从学生表开始,我们可以使用exists来检查他们是否至少注册了一个参与者少于 5 人的部分。

select s.*
from students s
where exists (
select 1
from enrollment e
group by section_id
having 
-- less than 5 participants
count(*) < 5
-- including the current student
and max(case when e.student_id = s.student_id then 1 else 0 end) = 1
)

诀窍是按部分分组,并使用having子句进行筛选。

最新更新