用join解决子查询错误ORA-01427

solving sub-query error ORA-01427 with join

我在冗长的 select 语句中有一个小的子查询,但我没有想法(无论我是否正在处理整个 select,我都会收到相同的 ORA-01427 错误语句或者如果我分离出子查询。我有以下内容:

NAME table
student_id_number field

TERM table
term_id field
student_id_number field

TEST view
test_id field
test_element field
student_id_number field
test_date field
score field

对于唯一的 term_id 值,当 test_id 字段 = A 且 test_element 字段 = COMP 时,我想 select 得分。我意识到每个唯一的术语 ID 和 student_id_number 字段可能有多个这些元素的有效组合,但 test_date 字段对于多行仍然是唯一的,我怀疑使用max(value) for score 或 test_date 可能会解决这个问题。但我不确定该怎么做。

尝试在 where 语句中插入 ROWNUM = 1 returns 所有 selected 记录的 table 的第一个分数。在 select 行中使用 max(score) returns 所有 selected 记录的最大分数值。

select
 a.term_id,
 a.student_id_number,
 (select ts.score
          from test_score ts
          left join term a on ts.student_id_number = a.student_id_number
          where ts.test_id = 'A' and ts.test_element = 'COMP') 
 from term a
 where a.term_id = '201701'

我想查看 term_id、student_id_number 和分数的列,但我得到了可怕的 ORA-01427 错误,也许(很可能)因为可能有多行匹配 student_id_number、test_id 和 test_element,但只有最近的分数是相关的(或者最高分数也与最近的分数相关)。这超出了我以前所做的任何事情的复杂性,我不确定如何(如果)解决这个问题。对这个没有经验的编码员的任何帮助或建议表示赞赏。谢谢

斯科特

使用聚合导致您的子查询可能 return 多行将创建 problem

select
 a.term_id,
 a.student_id_number,
 (select sum(ts.score)
          from test_score ts
          left join term a1 on ts.student_id_number = a1.student_id_number
          where ts.test_id = 'A' and ts.test_element = 'COMP') 
 from term a
 where a.term_id = '201701'

我认为不需要相关子查询,使用不带 WHERE 子句的 LEFT JOIN 就足够了:

select a.term_id, a.student_id_number, ts.score
  from test_score ts
  left join term a 
    on ts.student_id_number = a.student_id_number
   and ts.test_id = 'A' 
   and ts.test_element = 'COMP'
   and a.term_id = '201701'
   and to_char(ts.test_date,'yyyymm')=a.term_id;

并添加 and to_char(ts.test_date,'yyyymm')=a.term_id 归类。

您不需要在子查询中加入。您需要一个 correlation 子句——将子查询中的结果连接到外部查询中的行的东西:

select t.term_id, t.student_id_number,
      (select ts.score
       from test_score ts
       where ts.student_id_number = t.student_id_number and
             ts.test_id = 'A' and
             ts.test_element = 'COMP' and
             rownum = 1
      ) 
from term t
where t.term_id = '201701';

我添加了 WHERE rownum = 1 以将结果集限制为一行。您还可以使用聚合 - MIN()MAX()AVG()LISTAGG() 可能都是合适的。

此外,我更改了 table 别名,因此它们是 table 的缩写。任意字母会使查询更难阅读。