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

k3bvogb1  于 2023-04-05  发布在  Oracle
关注(0)|答案(3)|浏览(157)

以下问题基于Oracle提供的学生模式数据库:
以下子问题是相关的;确保你知道如何做前一个移动到下一个。
(a)编写一条SQL语句来显示分区ID和分区注册。
(b)编写SQL语句列出所有学生(使用以下格式:,以单列形式列出)。
不要显示任何重复的学生姓名,并按姓氏对结果进行排序。
这些问题不需要使用JOIN来回答。请解释为什么不使用JOIN也能做到这一点。
表STUDENT列:名、姓、学生ID
表ENROLLMENT列: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 Developer提供的学生模式数据库的情况下提出的

wd2eg0qa

wd2eg0qa1#

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

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

请注意,HAVINGWHERE不同,它在GROUP BY之后执行,并且可以使用聚合函数。
如果所有的学生都有不同的名字,DISTINCT关键字是不必要的。如果我们使用JOIN,它将是必要的,因为这将重复学生行。

i34xakig

i34xakig2#

我不明白你为什么不想要JOIN,但是你可以做以下事情,使用子查询和exists

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)
BA

fiddle

zxlwwiss

zxlwwiss3#

如果我理解正确的话,这里不需要嵌套的子查询。
从students表开始,我们可以使用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子句进行过滤。

相关问题