用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 的缩写。任意字母会使查询更难阅读。
我在冗长的 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 的缩写。任意字母会使查询更难阅读。