从子查询中选择返回太多行的数据

时间:2016-05-02 16:43:58

标签: sql oracle subquery

我确信这是构建我的理解的一个简单问题,但我处于心理障碍中,并且可以使用一些洞察力。我的查询生成了太多行,我认为这是因为我没有正确使用我的子查询。如果有人有资源帮助我理顺它,我会很感激!

所需结果一行选择一个名称,实质上将单个课程名称转移到同一行(当某些数据匹配时)。

测试安装程序我必须在开发服务器上的现有表的上下文中工作,但子查询正确地创建了一个简单的注册数据表。对于开发目的,对于两个不同的学生,在给定子查询中填充的注册记录不超过两个。

输出块1始终正确显示(无论是注册数据还是NULL),块2将显示NULL或正确的数据,块3将显示NULL或正确的数据。

返回四行数据,一行包含所有正确数据(块1,块2和块3),三行数据不正确(块1,NULL,块3;块1,块2,NULL;块1 ,NULL,NULL)。

这是我到目前为止的完整代码(有很多垃圾):

select distinct s.lastfirst as "Name", 
    s.home_room as "Teacher", 
    to_char(CASE WHEN (9000000 + satt.student_number) = s.student_number THEN satt.description END) as "School Absence",
    to_char(CASE WHEN s.student_number = satt.student_number THEN satt.description END) as "Extended Day Absence",
    to_char(CASE WHEN b1.studentid = s.id THEN b1.course_name END) as "Block 1", 
    to_char(CASE WHEN b2.studentid = s.id THEN b2.course_name END) as "Block 2",
    to_char(CASE WHEN b3.studentid = s.id THEN b3.course_name END) as "Block 3", 
    ' ' as "Signature"

from students s,

//Monday Block 1 Enrollment Generator
        (select cc.studentid, 
        c.course_name, 
        cc.course_number, 
        cc.expression, 
        cc.DATEENROLLED, 
        cc.DATELEFT
        from cc cc, courses c
        where cc.EXPRESSION like '%A%'
        and cc.SCHOOLID = 6

//!!Need to enter date variable here
        and (to_timestamp('19-SEP-2016') > cc.DATEENROLLED and to_timestamp('19-SEP-2016') < cc.DATELEFT)
        and c.course_number = cc.course_number
        and cc.expression like '%2%') b1,

//Monday Block 2 Enrollment Generator        
        (select cc.studentid, 
        c.course_name, 
        cc.course_number, 
        cc.expression, 
        cc.DATEENROLLED, 
        cc.DATELEFT
        from cc cc, courses c
        where cc.EXPRESSION like '%A%'
        and cc.SCHOOLID = 6

//!!Need to insert date variable here
        and (to_timestamp('19-SEP-2016') > cc.DATEENROLLED and to_timestamp('19-SEP-2016') < cc.DATELEFT)
        and c.course_number = cc.course_number
        and cc.expression like '%4%') b2,

//Monday Block 3 Enrollment Generator
        (select cc.studentid, 
        c.course_name, 
        cc.course_number, 
        cc.expression, 
        cc.DATEENROLLED, 
        cc.DATELEFT
        from cc cc, courses c
        where cc.EXPRESSION like '%A%'
        and cc.SCHOOLID = 6

//!!Need to enter date variable here
        and (to_timestamp('19-SEP-2016') > cc.DATEENROLLED and to_timestamp('19-SEP-2016') < cc.DATELEFT)
        and c.course_number = cc.course_number
        and cc.expression like '%6%') b3,

//Attendance record aggregator for the day specified
        (select s1.student_number, 
        attc.DESCRIPTION
        from ATTENDANCE att, students s1, ATTENDANCE_CODE attc, CALENDAR_DAY cd
        where att.studentid = s1.id
        and ATT_MODE_CODE = 'ATT_ModeMeeting'
        and att.ATTENDANCE_CODEID = attc.ID
        and att.calendar_dayid = cd.ID

//!!Need to insert date variable here
        and to_timestamp('19-SEP-2016') = cd.DATE_VALUE) satt

where s.last_name='HappyPants'

//!!Need to insert teacher variable here
and s.HOME_ROOM = 'RadTeacher'
and s.schoolid = 6

2 个答案:

答案 0 :(得分:0)

答案(男孩我觉得很傻)

我创建了一堆临时表,但(惊讶,惊讶)它是交叉加入。我在想,因为子查询中只有一条特定的记录可以匹配,所以它会在洗涤中出现。不。

添加LEFT JOIN与数据正确相关。

select distinct s.lastfirst as "Name", 
    s.home_room as "Teacher", 
    to_char(CASE WHEN (9000000 + satt.student_number) = s.student_number THEN satt.description END) as "School Absence",
    to_char(CASE WHEN s.student_number = satt.student_number THEN satt.description END) as "Extended Day Absence",
    to_char(CASE WHEN b1.studentid = s.id THEN b1.course_name END) as "Block 1", 
    to_char(CASE WHEN b2.studentid = s.id THEN b2.course_name END) as "Block 2",
    to_char(CASE WHEN b3.studentid = s.id THEN b3.course_name END) as "Block 3", 
    ' ' as "Signature"

from students s

//Monday Block 1 Enrollment Generator
    LEFT JOIN
        (select cc.studentid, 
        c.course_name, 
        cc.course_number, 
        cc.expression, 
        cc.DATEENROLLED, 
        cc.DATELEFT
        from cc cc, courses c
        where cc.EXPRESSION like '%A%'
        and cc.SCHOOLID = 6

//!!Need to enter date variable here
        and (to_timestamp('19-SEP-2016') > cc.DATEENROLLED and to_timestamp('19-SEP-2016') < cc.DATELEFT)
        and c.course_number = cc.course_number
        and cc.expression like '%2%') b1 on s.id = b1.studentid

//Monday Block 2 Enrollment Generator        
    LEFT JOIN
        (select cc.studentid, 
        c.course_name, 
        cc.course_number, 
        cc.expression, 
        cc.DATEENROLLED, 
        cc.DATELEFT
        from cc cc, courses c
        where cc.EXPRESSION like '%A%'
        and cc.SCHOOLID = 6

//!!Need to insert date variable here
        and (to_timestamp('19-SEP-2016') > cc.DATEENROLLED and to_timestamp('19-SEP-2016') < cc.DATELEFT)
        and c.course_number = cc.course_number
        and cc.expression like '%4%') b2 on s.id = b2.studentid

//Monday Block 3 Enrollment Generator
    LEFT JOIN
        (select cc.studentid, 
        c.course_name, 
        cc.course_number, 
        cc.expression, 
        cc.DATEENROLLED, 
        cc.DATELEFT
        from cc cc, courses c
        where cc.EXPRESSION like '%A%'
        and cc.SCHOOLID = 6

//!!Need to enter date variable here
        and (to_timestamp('19-SEP-2016') > cc.DATEENROLLED and to_timestamp('19-SEP-2016') < cc.DATELEFT)
        and c.course_number = cc.course_number
        and cc.expression like '%6%') b3 on s.id = b3.studentid

//Attendance record aggregator for the day specified
    LEFT JOIN
        (select s1.student_number, 
        attc.DESCRIPTION
        from ATTENDANCE att, students s1, ATTENDANCE_CODE attc, CALENDAR_DAY cd
        where att.studentid = s1.id
        and ATT_MODE_CODE = 'ATT_ModeMeeting'
        and att.ATTENDANCE_CODEID = attc.ID
        and att.calendar_dayid = cd.ID

//!!Need to insert date variable here
        and to_timestamp('19-SEP-2016') = cd.DATE_VALUE) satt on s.student_number = satt.student_number

where s.last_name='HappyPants'

//!!Need to insert teacher variable here
//and s.HOME_ROOM = 'RadTeacher'
and s.schoolid = 6
order by lastfirst

答案 1 :(得分:0)

您的查询正在进行交叉连接,这就是您获得多行的原因。请尝试使用INNER JOIN