однорядный подзапрос возвращает более одной строки 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


Я получаю следующую ошибку " Ошибка 20.12.2012 10: 05: 17 AM 0: 00: 00.093 жаба для аналитиков данных: ORA-01427: однорядный подзапрос возвращает более одной строки 1 78
"



Есть ли способ извлечь обе записи для "30" из таблицы ссылок? Потому что я хочу показать, что тестовый случай 30-это отказ из-за дефекта 500 & 400.



Большое Спасибо

507   2  

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". Это ваша проблема.

Какую из этих строк вы хотите?

Чтобы исправить подзапрос, вы можете либо сказать 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, вероятно, есть. здесь является ссылка на различные способы объединения строк в агрегацию в Oracle.

Comments

    Ничего не найдено.