【问题标题】:single-row subquery returns more than one row oracle单行子查询返回多行 oracle
【发布时间】:2023-03-12 03:50:01
【问题描述】:

我有如下三张表:

测试

    +--------------+--------+
    | 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: single-row subquery returns more than one row 1 78 "

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

非常感谢

【问题讨论】:

  • 您的 where 子句在子查询中被颠倒了
  • @BhrugeshPatel 你的意思是应该是where link1.test_case_id = test.test_case_id。我也试过了,但仍然得到同样的错误。
  • 您在链接中有两条记录,Test_Case_ID = 30。您要获取哪个 Defect_ID?

标签: sql oracle


【解决方案1】:

链接表中有两行的值为“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_concat 可能是可用的。 Here 是关于在 Oracle 的聚合中连接字符串的不同方法的参考。

【讨论】:

  • 有没有办法从链接表中检索“30”的记录?因为我想显示测试用例 30 由于缺陷 500 和 400 而失败。
  • 感谢 Gordon 抽出时间调查我的问题。
【解决方案2】:

您是否考虑过使用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 |

【讨论】:

  • 有没有办法从链接表中检索“30”的记录?因为我想显示测试用例 30 由于缺陷 500 和 400 而失败。
  • 这个查询确实检索了两条记录你看到演示了吗?
  • 感谢@bluefeet 抽出时间调查此事。只是想知道我们不能在输出的一条记录中而不是两行中同时显示defect_ids..我认为这听起来很愚蠢..只是想知道..谢谢
  • @javanoob 可以,什么版本的 oracle?
  • @javanoob 查看我的编辑,您可以使用LISTAGG 合并行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
  • 2022-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-01
  • 2013-05-25
相关资源
最近更新 更多