本声明中的子查询在哪里?

时间:2016-03-17 18:28:03

标签: sql oracle subquery

以下代码返回 ORA-01427:单行子查询返回多行,但我无法确定为什么会发生这种情况。该陈述的哪一部分被视为子查询?

SELECT
    ada.schoolid,
    s.dcid,
    s.lastfirst,
    s.grade_level,
    s.home_room,
    s.home_phone,
    SUM(ada.membershipvalue) - SUM(ada.attendancevalue) absences,
    SUM(ada.membershipvalue) membership,
    ROUND( ( SUM( ada.membershipvalue ) - SUM(ada.attendancevalue) ) / SUM( ada.membershipvalue ) * 100, 2) absenceRate
FROM
    students s
    JOIN schools schl ON schl.school_number = s.schoolid
    JOIN ps_adaadm_defaults_all ada ON ada.studentid = s.id and ada.schoolid in (87)
WHERE
    s.pl_language = '31516argul'
    AND to_date(ada.calendardate) >= to_date('9/01/2007', 'mm/dd/yyyy')
    AND to_date(ada.calendardate) <= to_date('6/20/2016','mm/dd/yyyy' )
    AND ada.membershipvalue > 0
GROUP BY 
    ada.schoolid, 
    s.dcid, 
    s.lastfirst, 
    s.grade_level, 
    s.home_room, 
    s.home_phone
ORDER BY
    s.lastfirst ASC

3 个答案:

答案 0 :(得分:0)

您有两种选择。无论您使用什么代码生成87都会导致问题(不太可能在评论中给出您的解释),或ps_adaadm_defaults_all导致问题。发布视图定义,我们可以弄清楚如何修复它,但是发生了什么,你的数据库正在选择一个执行计划,通过以不同的顺序连接表来打破该视图。

答案 1 :(得分:0)

由于您没有发布和采样输出数据......我们对您的数据视而不见。

我认为and ada.schoolid in (87)不应该在join语句中。 尝试在where子句

下移动它
where ada.schoolid in (87)
    AND s.pl_language = '31516argul'
    AND to_date(ada.calendardate) >= to_date('9/01/2007', 'mm/dd/yyyy')
    AND to_date(ada.calendardate) <= to_date('6/20/2016','mm/dd/yyyy' )
    AND ada.membershipvalue > 0

答案 2 :(得分:0)

您是加入学校(由schoolid),但没有加入学校ps_adaadm_defaults_all?然而,你在(87)中将ps_adaadm_defaults_all限制为schoolid。这似乎不一致 - 你从第一次加入获得所有学生的所有学生记录,然后ps_adaadm_defaults_all值(对于schoolid = 87)被用于学校的所有学校。