该语句中的子查询在哪里?

Posted

技术标签:

【中文标题】该语句中的子查询在哪里?【英文标题】:Where is the subquery in this statement? 【发布时间】:2016-03-17 18:28:03 【问题描述】:

以下代码返回 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

【问题讨论】:

这些都是表格吗?还是您正在使用某些视图?这是整个代码吗? @Lamak ps_adaadm_defaults_all 是一个视图。这是整个代码。 你能做到SELECT * FROM ps_adaadm_defaults_all 吗? 这是您正在运行并收到错误的确切代码吗? 87 总是这样硬编码吗? 你也可以发布该视图的定义吗?虽然不太可能,但我见过一些情况,视图中的一些奇怪的东西会导致它们的连接方式出现意外错误。 【参考方案1】:

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

【讨论】:

【参考方案2】:

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

我相信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

【讨论】:

哪个表有多行唯一id的数据? Oracle 通常不关心内部连接,并且会提出相同的计划和访问/过滤谓词;无论如何,它在内部都会用旧语法重写。我想如果视图以某种方式导致问题,那么它可能会产生一些影响;我对此表示怀疑,但检查起来会很有趣。 我相信其中一张表有多行数据是不同的`ada.schoolid`;我想了解更多关于表格数据的信息。【参考方案3】:

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

【讨论】:

ada.studentid = s.id 仍将间接限制为一所学校。或至少对与该学校有关联的所有学生;我想一个学生可能会被列入不止一所学校。这并没有解决所看到的错误,尽管这可能会影响 Oracle 如何在内部重写查询以处理(显然显然非常复杂)视图。也许它只影响那些学生也在其他学校的学校。

以上是关于该语句中的子查询在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

sql语句update语句中嵌套的子查询该怎么写?

MySQL基础语法之子链接查询和特殊查询(union 和 limit)

选择语句中的子查询如何在 oracle 中工作

mysql的子查询中有统计语句 我该如何优化

MYSQLupdate/delete/select语句中的子查询

[转]HQL中的子查询