корпус переключателя coalesce mybatis
Я использую случай переключения coalesce mybatis в своем запросе, где я получаю ошибку, например
Ошибка запроса базы данных. Причина: java.sql.SQLException: ORA-01427: однострочный подзапрос возвращает более одной строки
это мой запрос
(select
(case when (coalesce(t1.col1,t2.col1, t1.col2, t1.col3) is null)
then (select sysdate from dual)
else (coalesce(t1.col1,t2.col1, t1.col2, t1.col3))
end )
from table1 t1
join table2 t2
on t1.id IN (t2.id))
заранее спасибо
2 ответа
Кажется, у вас много (), но в целом вы должны использовать оператор =, а не IN (t2.id) для соединения t2.id
select
case when coalesce(t1.col1,t2.col1, t1.col2, t1.col3) is null
then sysdate
else coalesce(t1.col1,t2.col1, t1.col2, t1.col3)
end
from table1 t1
join table2 t2 on t1.id = t2.id
И, глядя на код, который вы разместили в образце, у вас есть выбор в качестве результата столбца, и этот выбор возвращает несколько строк (это вызывает ошибку). У вас также есть микс синтаксиса соединения, некоторые из которых основаны на явном синтаксисе соединения, некоторые на основе старого синтаксиса неявного соединения на основе имени таблицы, разделенной запятыми, и условия where. Вы должны попробовать использовать это
<select id="Trigger" parameterType="hashmap" resultType="java.util.HashMap" flushCache="true">
SELECT
select case when coalesce(table1.col1, table2.col2,table1.col3, table1.col4) is null
then sysdate
else coalesce(table1.col1, table2.col2,table1.col3, table1.col4) end as "ProgressDate"
, table3.id as "ID"
from table1
INNER join table2 on table1.id = table2.id
INNER JOIN table3 ON table1.id = table3.id
INNER JOIN table4 table2.action = table4.action
WHERE table3.transaction = #{inputvaluepassed}
</select>
Запрос, который вы упомянули в вопросе, заменяет скалярный подзапрос, включенный в другой... основной запрос. Я отформатировал весь запрос (для удобства чтения), и он выглядит так:
SELECT
(
select case when coalesce(table1.col1, table2.col2,table1.col3,
table1.col4) is null
then (select sysdate from dual)
else coalesce(table1.col1, table2.col2,table1.col3, table1.col4)
end
from table1
join table2 on table1.id = table2.id
) as "ProgressDate",
table3.id as "ID"
FROM table3, table1, table2, table4
WHERE table3.transaction = #{inputvaluepassed}
AND table1.id = table3.id
AND table2.id=table1.id and table2.action = table4.action
Теперь, по определению, скалярные подзапросы могут возвращать только ноль или одну строку. В вашем случае кажется, что во время выполнения этот подзапрос возвращает несколько строк, и основной запрос дает сбой.
Вам нужно будет каким-то образом создать не более одной строки: возможно, путем агрегирования строк (используя GROUP BY
), возможно, выбрав только одну строку из набора результатов (используя LIMIT
); Есть и другие варианты. Если мы выберем ограничить количество строк до 1, ваш запрос может выглядеть так:
SELECT
(
select case when coalesce(table1.col1, table2.col2,table1.col3,
table1.col4) is null
then (select sysdate from dual)
else coalesce(table1.col1, table2.col2,table1.col3, table1.col4)
end
from table1
join table2 on table1.id = table2.id
limit 1 -- added this line
) as "ProgressDate",
table3.id as "ID"
FROM table3, table1, table2, table4
WHERE table3.transaction = #{inputvaluepassed}
AND table1.id = table3.id
AND table2.id=table1.id and table2.action = table4.action
Это всего лишь одно из возможных дешевых решений проблемы. Лучшее понимание того, как выбрать правильную строку из нескольких, может дать лучшее решение.