ORA-01427单行子查询返回多于 1 行
Posted
技术标签:
【中文标题】ORA-01427单行子查询返回多于 1 行【英文标题】:ORA-01427 Single row subquery returns more than 1 row 【发布时间】:2020-02-27 19:34:12 【问题描述】:这个错误似乎很流行,有很多相关的答案。但是,现有的答案似乎不适用于我的情况。
我正在使用 2 个表来简化我的案例:Test1 和 Test3(参见插图)
我要做的是尝试在 test3 表中查找与字段 value1 中的值不匹配的记录(如果字段 check_condition1 = 1,如果它是 0,那么我不在乎)
所以在这个特定场景中,基本上结果应该类似于这个查询:
select distinct t3.* from test3 t3, test1 t1
where t3.department=t1.department
and t3.value1 not in ('A','B');
但是,如果我使用这种说法:
select distinct t3.* from test3 t3, test1 t1
where t3.department=t1.department
and t3.value1 not in
(
case t1.CHECK_CONDITION1
when 0 then
(select '1' from dual where 1=2)
when 1 then
( select value1 from test1 where department=t3.DEPARTMENT)
end
)
我收到了这条消息:
ORA-01427: single-row subquery returns more than one row
01427. 00000 - "single-row subquery returns more than one row"
*Cause:
*Action:
我认为我的子查询“从 test1 where department=t3.DEPARTMENT 中选择 value1”应该返回一个 t3.value1 的集合以进行检查。
应如何更正该陈述?我的目标是使用 Test1 表作为控制表,字段 Check_condition1、check_condition2 是可以打开和关闭的“开关”,而无需更改主查询。 请告知我的想法是否有意义。
附件是创建表 test1 和 test3 的脚本,以便更轻松地复制我的问题。
CREATE TABLE "TEST1"
( "DEPARTMENT" NUMBER(3,0),
"VALUE1" VARCHAR2(26 BYTE),
"VALUE2" VARCHAR2(26 BYTE),
"CHECK_CONDITION1" NUMBER(3,0),
"CHECK_CONDITION2" NUMBER(3,0)
)
Insert into TEST1 (DEPARTMENT,VALUE1,VALUE2,CHECK_CONDITION1,CHECK_CONDITION2) values (1,'A','Z',1,0);
Insert into TEST1 (DEPARTMENT,VALUE1,VALUE2,CHECK_CONDITION1,CHECK_CONDITION2) values (1,'B','Y',1,0);
CREATE TABLE "TEST3"
( "DEPARTMENT" NUMBER(3,0),
"VALUE1" VARCHAR2(26 BYTE),
"VALUE2" VARCHAR2(26 BYTE),
"VALUE3" VARCHAR2(26 BYTE)
);
Insert into TEST3 (DEPARTMENT,VALUE1,VALUE2,VALUE3) values (1,'A','T','Whatever');
Insert into TEST3 (DEPARTMENT,VALUE1,VALUE2,VALUE3) values (1,'Z','Y','Whatever');
Insert into TEST3 (DEPARTMENT,VALUE1,VALUE2,VALUE3) values (1,'B','Y','Whatever');
【问题讨论】:
【参考方案1】:来自CASE
expression documentation:
对于简单和搜索的
CASE
表达式,所有return_expr
s 必须具有相同的数据类型(CHAR
、VARCHAR2
、NCHAR
或NVARCHAR2
、NUMBER
、@987654331 @ 或BINARY_DOUBLE
) 或都必须具有数字数据类型。如果所有返回表达式都具有数字数据类型,则 Oracle 确定具有最高数字优先级的参数,将剩余的参数隐式转换为该数据类型,并返回该数据类型。
CASE
语句的 return_expr
需要一个值,因此您的子查询:
( select value1 from test1 where department=t3.DEPARTMENT)
是什么引发了异常。
改为在子查询上使用过滤器:
select distinct t3.*
from test3 t3
INNER JOIN test1 t1
ON ( t3.department=t1.department )
WHERE t3.value1 not in (
select value1
from test1
where department=t3.DEPARTMENT
AND t1.CHECK_CONDITION1 = 1
)
对于您的测试数据,输出:
部门 |价值1 |价值2 |价值3 ---------: | :----- | :----- | :-------- 1 | Z |是 |任何
db小提琴here
【讨论】:
我明白了。感谢@MT0 和 LittleFoot 的更正和解释。【参考方案2】:我猜应该是这样的:
SQL> select distinct t3.*
2 from test3 t3 join test1 t1 on t3.department=t1.department
3 where t3.value1 not in
4 (select t1.value1 from test1 t1
5 where t1.department = t3.department
6 and 1 = case when t1.check_condition1 = 1 then 1
7 else 0
8 end
9 );
DEPARTMENT VALUE1 VALUE2 VALUE3
---------- ---------- ---------- ----------
1 Z Y Whatever
SQL>
如果条件为0,你说你不在乎,所以:
SQL> update test1 set check_condition1 = 0;
2 rows updated.
SQL> select distinct t3.*
2 from test3 t3 join test1 t1 on t3.department=t1.department
3 where t3.value1 not in
4 (select t1.value1 from test1 t1
5 where t1.department = t3.department
6 and 1 = case when t1.check_condition1 = 1 then 1
7 else 0
8 end
9 );
DEPARTMENT VALUE1 VALUE2 VALUE3
---------- ---------- ---------- ----------
1 B Y Whatever
1 A T Whatever
1 Z Y Whatever
SQL>
【讨论】:
感谢您的调查。这正是我感到困惑的地方。因此,case 没有将集合作为返回值,这导致了异常。以上是关于ORA-01427单行子查询返回多于 1 行的主要内容,如果未能解决你的问题,请参考以下文章
Oracle SQL:ORA-01427:单行子查询返回多于一行
ORA-01427: 单行子查询返回多于一行 ,,WHEN USING SELECT COUNT