Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using tuples in ORACLE IN clause and a condition for one element in the tuple

I have seen many questions here for using tuples in the IN clause. My situation is a little different from the others. General usage of tuples in IN clause will look as below

    Select * from MY_TABLE
    where (id,name,date) IN ((1,'new','10-JUL-13'),(2, 'old','09-JUN-13'))

Considering the above query, my requirement is to retrieve the records with id and name values along with date in a particular range. lets say

    effectiveDate <= date <= termDate  

I'm using ORACLE database and MyBatis ORM. I'll get data as a list of objects, so when I use mybatis I can use a foreach/for loop to populate the tuples, but when I want to use condition for one of those values from the object.

When I use Mybatis for one value read from a list, the where clause as below

    <where>
        and (id,name) IN
   <foreach item="object" collection="data" open="(" separator=","close=")">
    (#{object.id},#{object.name})
   </foreach>
    </where>

I have to include the condition in the loop as well.

Waiting for the expert advice. Thanks in advance.

like image 679
Bharath ABK Avatar asked Jul 17 '13 01:07

Bharath ABK


People also ask

Can we use having and where clause together in Oracle?

Only the rows that meet the conditions in the WHERE clause are grouped. The HAVING clause is then applied to the rows in the result set.

What is the with clause in Oracle?

The SQL WITH clause was introduced by Oracle in the Oracle 9i release 2 database. The SQL WITH clause allows you to give a sub-query block a name (a process also called sub-query refactoring), which can be referenced in several places within the main SQL query.


2 Answers

Are you looking for something like this?

select *
from MY_TABLE
where (id, name) in ((1,'new'), (2, 'old')) and
      date between effectiveDate and termDate

This looks for the pairs in a list and then checks for the dates between a range of dates.

EDIT:

I think you want to break this into multiple clauses, one for each set of values:

where (id = 1 and name = 'new' and date between eff1 and term1) or
      (id = 2 and name = 'old' and date between eff2 and term2) or
      . . .
like image 146
Gordon Linoff Avatar answered Oct 25 '22 15:10

Gordon Linoff


The above solution for my question is rewritten below for Mybatis users

    <where>
    <foreach item="object" collection="data" separator="OR">
      (id = #{object.id} AND name = #{object.name} AND (effDt < #{object.date} < termDt))
    </foreach>
    </where>

There won't be a big performance difference when you use either IN or OR to separate the data/conditions in the WHERE clause.

    FYI : *http://stackoverflow.com/questions/3074713/in-vs-or-in-the-sql-where-clause*
like image 2
Bharath ABK Avatar answered Oct 25 '22 16:10

Bharath ABK