查找子查询中是否存在一行

Looking for whether a row exists in a subquery

剧透警报:我是 Oracle 的新手。
我有四个 table:注册人数、courses/sections、标准和成绩。

我们运行获得荣誉榜。我对前三个 table 有疑问,它们添加了满足荣誉榜要求所需的各种约束。然后我们看成绩table。 如果他们有有效的注册,在有效的课程中,符合有效的标准,然后计算他们的分数。如果他们的分数数量达到阈值,那么他们将获得荣誉。

这段代码没有优化,而且很可能可以用 better/more 紧凑的方式完成,我敢肯定——但是,它一年只得到 运行 几次,所以我'愿意权衡优化以增加人类可读性,以便我可以继续学习基础知识。到目前为止我有:

WITH validCC (SELECT CC.ID AS CCID,
    CC.STUDENTID AS STUDENTID, 
    CC.SECTIONID AS SECTIONID, 
    CC.TERMID AS TERMID, 
    STUDENTS.DCID AS STUDENTSDCID
FROM CC
    INNER JOIN STUDENTS ON CC.STUDENTID = STUDENTS.ID
WHERE TERMID in (2700,2701)
    AND CC.SCHOOLID = 406;
),  --end validCC

validCrsSect (SELECT SECTIONS.ID AS SECTIONID,
    SECTIONS.DCID AS SECTIONSDCID,
    SECTIONS.EXCLUDEFROMHONORROLL AS SECTHR,
    COURSES.COURSE_NUMBER AS COURSE_NUMBER,
    COURSES.COURSE_NAME AS COURSE_NAME,
    COURSES.EXCLUDEFROMHONORROLL AS CRSHR
FROM SECTIONS
    INNER JOIN COURSES ON SECTIONS.COURSE_NUMBER = COURSES.COURSE_NUMBER AND SECTIONS.SCHOOLID = COURSES.SCHOOLID
WHERE SECTIONS.TERMID IN (2700,2701)
    AND SECTIONS.SCHOOLID = 406
    AND SECTIONS.EXCLUDEFROMHONORROLL = 0
    AND COURSES.EXCLUDEFROMHONORROLL = 0
), --end validCrsSect

validStandard (SELECT STANDARDID,
    IDENTIFIER,
    TRANSIENTCOURSELIST
FROM STANDARD
WHERE isActive = 1
    AND YEARID = 27
    AND ( instr (STANDARD.identifier, 'MHS.TS', 1 ,1) > 0     --Is a valid standard for this criteria:  MHS TS
        or STANDARD.identifier = 'MHTC.TS.2'                  --or MHTC TS
        or STANDARD.identifier = 'MHTC.TS.4'  )
), --end validStandard

--sgsWithChecks ( 
SELECT sgs.STANDARDGRADESECTIONID AS SGSID,
    sgs.STUDENTSDCID as STUDENTSDCID,
    sgs.STANDARDID AS STANDARDID,
    sgs.STORECODE AS STORECODE,
    sgs.SECTIONSDCID AS SECTIONSDCID,
    sgs.YEARID AS YEARID,
    sgs.STANDARDGRADE AS STANDARDGRADE,
    (select count(CCID) from validCC INNER JOIN STANDARDGRADESECTION sgs ON sgs.STUDENTSDCID = validCC.STUDENTSDCID and sgs.SECTIONSDCID = validCC.SECTIONID) as CC_OK,
    (select count(SECTIONID) from validCrsSection  INNER JOIN STANDARDGRADESECTION sgs ON  sgs.SECTIONSDCID = validCrsSect.SECTIONSDCID) AS CRS_OK,
    (select count(STANDARDID) from validStandard  INNER JOIN STANDARDGRADESECTION sgs ON  sgs.STANDARDID = validStandard.STANDARDID) AS STD_OK
FROM STANDARDGRADESECTION sgs

将'OK'列放在vGradestable中的目的是因为最后的SELECT(不包括)通过并计算某些分数过滤的实例检查。

令人沮丧的是,学生 table 和班级 table 中都有两个 ID(而且这不是相同的数据)。所以当我去 link 一切时,一些 tables 使用 ID 作为 FK,其他人使用 DCID 作为 FK;而且我必须引入额外的 table 才能进行转换。我猜这样会使连接更有趣。

每个单独的查询都独立工作,但我无法让最终的 select count() 来提取他们的数据。我尝试将初始查询嵌入为子查询,但我无法将 studentid 传递给它们,它会 运行 查询每个学生,而不是在开始时查询一次。

我当前的错误是:

Error starting at line : 13 in command -
    SECTIONS.DCID AS SECTIONSDCID,
Error report -
Unknown Command

但是在它说未知 table 并引用连接语句的最后一行之前。所有 table 名称均有效。 想法?

我用一个简单的 WHERE 条件替换了 INNER JOIN。这似乎有效。

(SELECT COUNT (CCID) FROM validCC WHERE sgs.STUDENTSDCID = validCC.STUDENTSDCID and sgs.SECTIONSDCID = validCC.SECTIONID) as CC_OK,
(SELECT COUNT (SECTIONID) FROM validCrsSect WHERE sgs.SECTIONSDCID = validCrsSect.SECTIONSDCID) AS CRS_OK,
(SELECT COUNT (STANDARDID) FROM validStandard WHERE sgs.STANDARDID = validStandard.STANDARDID) AS STD_OK

我删除了 validStandard 末尾的逗号并将 from validCrsSection 替换为 from validCrsSect(假设它是指 WITH 子句并且没有另一个 validCrsSection table)。我还猜测计数是针对当前 sgs 行而不是整个 table 的计数。我这样做:

with validcc as
     ( select cc.id as ccid
            , cc.studentid
            , cc.sectionid
            , cc.termid
            , st.dcid as studentsdcid
       from   cc
              join students st on st.id = cc.studentid
       where  cc.termid in (2700, 2701)
       and    cc.schoolid = 406
     )
   , validcrssect as
     ( select s.id as sectionid
            , s.dcid as sectionsdcid
            , s.excludefromhonorroll as secthr
            , c.course_number
            , c.course_name
            , c.excludefromhonorroll  as crshr
       from   sections s
              join courses c
                   on  c.course_number = s.course_number
                   and c.schoolid = s.schoolid
       where  s.termid in (2700, 2701)
       and    s.schoolid = 406
       and    s.excludefromhonorroll = 0
       and    c.excludefromhonorroll = 0
     )
   , validstandard as
      ( select standardid
             , identifier
             , transientcourselist
        from   standard
        where  isactive = 1
        and    yearid = 27
        and    (   instr(standard.identifier, 'MHS.TS', 1, 1) > 0
                or standard.identifier in ('MHTC.TS.2','MHTC.TS.4') )
     )
select sgs.standardgradesectionid as sgsid
     , sgs.studentsdcid
     , sgs.standardid
     , sgs.storecode
     , sgs.sectionsdcid
     , sgs.yearid
     , sgs.standardgrade
     , ( select count(*) from validcc
         where  validcc.studentsdcid = sgs.studentsdcid
         and    validcc.sectionid = sgs.sectionsdcid ) as cc_ok
     , ( select count(*) from validcrssect
         where  validcrssect.sectionsdcid = sgs.sectionsdcid ) as crs_ok
     , ( select count(*) from validstandard
         where  validstandard.standardid = sgs.standardid ) as std_ok
from   standardgradesection sgs;

这适用于六个 table 定义 reverse-engineered 为:

create table students
( id integer not null
, dcid integer );

create table cc
( id integer
, studentid integer
, sectionid integer
, termid integer
, schoolid integer );

create table courses
( course_number integer
, course_name varchar2(30)
, excludefromhonorroll integer
, schoolid integer );

create table sections
( id integer not null
, dcid integer
, excludefromhonorroll integer
, termid integer
, schoolid integer
, course_number integer );

create table standard
( standardid integer
, identifier varchar2(20)
, transientcourselist varchar2(50)
, isactive integer
, yearid integer );

create table standardgradesection
( standardgradesectionid integer
, studentsdcid integer
, standardid integer
, storecode integer
, sectionsdcid integer
, yearid integer
, standardgrade integer );