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