coalesce mybatis switch case

2.2k Views Asked by At

Iam using coalesce mybatis switch case in my query, where iam getting error like

Error querying database. Cause: java.sql.SQLException: ORA-01427: single-row subquery returns more than one row

this is my query

(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))

Thanks in advance

2

There are 2 best solutions below

7
On BEST ANSWER

Seems you have a lot of () but overall you should use = operator and not IN (t2.id) for join 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

And looking at the code you posted in sample you have a select as a column result and this select return several rows, ( this raise the error). You also have a mixin of join syntax some based on explicit join syntax some based on old implicit join syntax based on comma separated table name and where condition. You should try using this

<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> 
1
On

The query you mention in the question takes the place of a scalar subquery included in another... main query. I formatted the whole query (for readability) and it looks like this:

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

Now, by definition, scalar subqueries can only return zero or one row. In your case it seems that at runtime this subquery is returning multiple rows, and the main query crashes.

You'll need to somehow produce a single row at most: maybe by aggregating the rows (using GROUP BY), maybe by picking one row only from the result set (using LIMIT); there are other options. If we choose the to limit the rows to 1 at most your query could look like:

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

This is just one possible cheap solution to the issue. A better understanding on how to pick the right row over multiples ones can produce a better solution.