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_exprs 必须具有相同的数据类型(CHARVARCHAR2NCHARNVARCHAR2NUMBER、@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 行的主要内容,如果未能解决你的问题,请参考以下文章

ORA-01427单行子查询返回多于 1 行

ORA-01427 单行子查询返回多于一行

Oracle SQL:ORA-01427:单行子查询返回多于一行

ORA-01427: 单行子查询返回多于一行 ,,WHEN USING SELECT COUNT

我得到那个错误 ORA-01427: 单行子查询返回多于一行

Oracle APEX 交互式报告中的错误 - ORA-01427:单行子查询返回多于一行