单行子查询返回多行oracle

时间:2012-12-20 14:59:53

标签: sql oracle

我有三张如下表:

测试

    +--------------+--------+
    | Test_Case_ID | Status |
    +--------------+--------+
    |           10 | PASS   |
    |           20 | FAIL   |
    |           30 | FAIL   |
    +--------------+--------+

缺陷

    +-----------+
    | Defect_ID |
    +-----------+
    |       500 |
    |       400 |
    +-----------+

link1

    +--------------+-----------+
    | Test_Case_ID | Defect_ID |
    +--------------+-----------+
    |           20 |       500 |
    |           30 |       500 |
    |           30 |       400 |
    +--------------+-----------+

我正在尝试以下查询

select 
test.test_case_id,
test.status,
case when test.status = 'FAIL' then 
(select link1.defect_id 
from link1 
where 
test.test_case_id = link1.test_case_id) 
end as defect1_id
from test test

我收到以下错误“错误12/20/2012 10:05:17 AM 0:00:00.093 Toad for Data Analysts:ORA-01427:单行子查询返回多行1 78 “

有没有办法从链接表中检索“30”的两个记录?因为我想显示测试用例30由于缺陷500而导致失败。 400。

非常感谢

2 个答案:

答案 0 :(得分:4)

链接表中有两行,其值为" 30"。这是你的问题。

您想要哪一行?

要修复子查询,您可以说select max(link1.defect_id)或将and rownum = 1添加到where子句。

你想要的东西可能更复杂。这个版本如何将缺陷连接成一个字符串:

select t.test_case_id, t.status,
       listagg(cast(l.defect_id as varchar(32)) within group (order by l.defect_id) as defects
from test t left join
     link1 l
     on t.test_case_id = l.test_case_id
group by t.test_case_id, t.status

您没有指定Oracle的版本。如果listagg不可用,则可能是wm_concatHere是关于在Oracle中聚合中连接字符串的不同方法的参考。

答案 1 :(得分:3)

您是否考虑使用JOIN而不是子查询:

select 
  t.test_case_id,
  t.status,
  case when t.status = 'FAIL' then l.defect_id  
    end as defect1_id
from test t
left join link1 l
  on t.test_case_id = l.test_case_id

请参阅SQL Fiddle with Demo

这将返回两个记录,然后您可以决定在最终结果中返回哪个项目。

结果:

| TEST_CASE_ID | STATUS | DEFECT1_ID |
--------------------------------------
|           20 |   FAIL |        500 |
|           30 |   FAIL |        500 |
|           30 |   FAIL |        400 |
|           10 |   PASS |     (null) |

根据您的评论,如果您使用的是Oracle 11g,那么您可以使用LISTAGG()函数将记录合并为一行:

select 
  t.test_case_id,
  t.status,
  case 
    when t.status = 'FAIL' 
    then listagg(l.defect_id, ', ')
          within group (order by l.defect_id)
  end as defect1_id
from test t
left join link1 l
  on t.test_case_id = l.test_case_id
group by t.test_case_id, t.status

请参阅SQL Fiddle with Demo

结果:

| TEST_CASE_ID | STATUS | DEFECT1_ID |
--------------------------------------
|           10 |   PASS |     (null) |
|           20 |   FAIL |        500 |
|           30 |   FAIL |   400, 500 |
相关问题