如何处理单行子查询返回多个行错误与case语句

时间:2016-09-13 15:05:18

标签: oracle oracle-sqldeveloper

我正在构建一个涉及案例陈述的Oracle查询。

SELECT 
  CASE WHEN 
    ((SELECT agent_or_group_id from trans_slot where slot_id = 
    (SELECT slot_id from trans_slot where slot_alias = 'PP' and measure_expiration > sysdate)) > 0) 
/*The below subquery returns 1 row*/
  THEN (SELECT agent_or_group_id from trans_slot where slot_id = 
    (SELECT slot_id from trans_slot where slot_alias = 'PP' and measure_expiration > sysdate))
  ELSE 
/* The below subquery returns 2 rows*/
   (SELECT child_agent_id FROM agent_object_group_member WHERE parent_agent_id IN
    (SELECT agent_or_group_id FROM trans_slot WHERE slot_id IN
     (SELECT slot_id FROM trans_slot WHERE slot_alias = 'PP' AND measure_expiration > sysdate)
     )
    ) 
END
 "Agent_ID" from DUAL;

当子查询独立运行时,它们运行正常。但是运行整个查询会返回

ORA-01427: single-row subquery returns more than one row
01427. 00000 -  "single-row subquery returns more than one row"
*Cause:    
*Action:

1 个答案:

答案 0 :(得分:1)

如果我明白你所追求的是什么,你就不能那样做。您需要使用左外连接,然后选择要显示的列值。

以下是基于您提供的SQL的简化示例:

WITH t1 AS (SELECT 1 ID FROM dual UNION ALL
            SELECT 0 ID FROM dual UNION ALL
            SELECT 2 ID FROM dual),
     t2 AS (SELECT 10 child_id, 0 parent_id FROM dual UNION ALL
            SELECT 20 child_id, 0 parent_id FROM dual UNION ALL
            SELECT 30 child_id, 1 parent_id FROM dual UNION ALL
            SELECT 40 child_id, 2 parent_id FROM dual)
---- end of mimicking two tables with the sample data in them. See the query below:
SELECT COALESCE(t2.child_id, t1.id) ID
FROM   t1
       LEFT OUTER JOIN t2 ON (t1.id = t2.parent_id AND t1.id = 0);

        ID
----------
        10
        20
         2
         1

在这里,我使用了t1和t2子查询来模仿原始查询中从主子查询中获得的输出。

然后我们只在t1.id = 0的情况下将t2连接到t1。通过这样做,你可以简单地选择t2.child_id值(如果存在),否则使用t1.id值。

(我知道在你的例子中,t1等效子查询只会生成1行,基于你所说的,但我已经包含了3行,这样你就可以根据不同的id看到结果。 )

ETA:

在您的情况下,上面示例中的t1子查询将是:

SELECT agent_or_group_id
from   trans_slot
where  slot_id = (SELECT slot_id
                  from   trans_slot
                  where  slot_alias = 'PP'
                  and    measure_expiration > sysdate)

和t2子查询将是:

SELECT child_agent_id
FROM   agent_object_group_member
WHERE  parent_agent_id IN (SELECT agent_or_group_id
                           FROM trans_slot
                           WHERE slot_id IN (SELECT slot_id
                                             FROM   trans_slot
                                             WHERE slot_alias = 'PP'
                                             AND measure_expiration > sysdate))