3

我在一个冗长的 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 时选择一个分数。我意识到每个唯一的术语 ID 和 student_id_number 字段可能有多个这些元素的有效组合,但是 test_date 字段对于多行仍然是唯一的,我怀疑使用 max(value) 作为 score 或 test_date可能会解决这个问题。但我不确定如何做到这一点。

尝试在 where 语句中插入 ROWNUM = 1 会返回表中所有选定记录的第一个分数。在选择行中使用 max(score) 返回所有选定记录的最大得分值。

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 和 score 的列,但我得到了可怕的 ORA-01427 错误,可能(可能)因为可能有多行匹配 student_id_number、test_id 和 test_element,但是只有最近的分数是相关的(或与最近的分数相反,最高分数也将是相关的)。这超出了我之前所做的任何事情的复杂性,我不确定如何(如果)解决这个问题。对此缺乏经验的编码员的任何帮助或建议表示赞赏。谢谢。

斯科特

4

3 回答 3

0

使用聚合导致您的子查询可能返回多行,这将创建问题

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'
于 2019-07-31T10:12:26.660 回答
0

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

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排序规则。

于 2019-07-31T10:25:05.987 回答
0

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

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()可能都合适。

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

于 2019-07-31T10:55:06.787 回答