3

我有一个看起来像这样的查询:

SELECT 'FY2000' AS FY, COUNT(DISTINCT SGBSTDN_PIDM) AS CHEM_MAJORS
FROM SATURN.SGBSTDN, SATURN.SFRSTCR
WHERE SGBSTDN_PIDM = SFRSTCR_PIDM
  AND SGBSTDN_TERM_CODE_EFF = (SELECT MAX(SGBSTDN_TERM_CODE_EFF)
                               FROM SATURN.SGBSTDN
                               WHERE SGBSTDN_TERM_CODE_EFF <=  '200002'
                                 AND SGBSTDN_PIDM = SFRSTCR_PIDM)
  AND SGBSTDN_MAJR_CODE_1 = 'CHEM'
  AND SFRSTCR_TERM_CODE BETWEEN '199905' AND '200002'
  AND (SFRSTCR_RSTS_CODE LIKE 'R%' OR SFRSTCR_RSTS_CODE LIKE 'W%')
  AND SFRSTCR_CREDIT_HR >= 1

它返回 48 的计数,我认为这是正确的。但是,我不明白为什么子查询不需要SATURN.SFRSTCR在 FROM 子句中才能引用SFRSTCR_PIDM. 我认为子查询是自包含的,看不到查询的其余部分?

但是,如果我将 SATURN.SFRSTCR 添加到子查询中,计数将更改为 22。如果我AND SGBSTDN_PIDM = SFRSTCR_PIDM从子查询中取出,计数也会更改为 22。有人可以向我解释一下吗?

4

3 回答 3

6

您有一个相关的子查询。这与非相关子查询有点不同,因为它可以包含对外部表的引用。

使用相关子查询时,始终为所有表引用使用表别名。一般来说,这是一个好主意,但对于相关的子查询应该更加注意。

AND SGBSTDN_TERM_CODE_EFF = (SELECT MAX(SGBSTDN.SGBSTDN_TERM_CODE_EFF)
                             FROM SATURN.SGBSTDN
                             WHERE SGBSTDN.SGBSTDN_TERM_CODE_EFF <=  '200002'
                               AND SGBSTDN.SGBSTDN_PIDM = SFRSTCR.SFRSTCR_PIDM
                            )

对于SFRSTCR.SFRSTCR_PIDM(和其他条件)的每个值,子查询获取最大日期。

在大多数 SQL 版本中,相关子查询允许在fromwherehaving子句中。(他们也可能被允许进入order by。)

于 2013-08-06T13:50:59.127 回答
2

相关子查询(即 WHERE 子句中的子查询)可以引用外部查询中的列。它们不同于内联视图(即 FROM 子句中的子查询),后者无法看到父查询中定义的列。

您做对了:子查询将首先SFRSTCR_PIDM在其范围 ( ) 中查找该列SATURN.SGBSTDN,然后在外部查询中查找它。

于 2013-08-06T13:51:08.247 回答
0

您列出的子查询将采用正在处理的外部级别的任何当前记录并使子查询可用,这就是您不需要明确地将其包含在子查询中的原因。如果该列是唯一可识别的,则不需要 alias.column 引用,只需使用 columnName 引用即可。

但是,子查询的性能通常很差,因为子查询是针对正在处理的每条记录运行的。通常使用连接,但每个查询都有自己的需求,并且您在子查询级别获得 MAX() 。

于 2013-08-06T13:51:44.107 回答