Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change a UNION to a IN clause?

I need to get a maximum of 3 distinct records from the same table, so currently I'm doing:

SELECT 1, mycolumn FROM mytable WHERE id = @firstId
UNION ALL
SELECT 2, mycolumn FROM mytable WHERE id = @secondId
UNION ALL
SELECT 3, mycolumn FROM mytable WHERE id = @thirdId

The actual SELECT part contains over 20 columns and the FROM part contains a number of JOINs. The first column is a constant and is always fixed depending on the record. I don't know how many records might return. It could be anything from 0 to 3 records.

Is it possible to change the above query so that it uses IN like this:

SELECT ???, mycolumn FROM mytable WHERE id IN (@firstId, @secondId, @thirdId)

But how do I explicitly map each record to the fixed constant if I use IN?

like image 217
Ivan-Mark Debono Avatar asked Feb 11 '19 08:02

Ivan-Mark Debono


2 Answers

You may use a CASE expression here with a single query:

SELECT
    CASE id WHEN @firstId  THEN 1
            WHEN @secondId THEN 2
            WHEN @thirdId  THEN 3 END AS val,
    mycolumn
FROM mytable
WHERE
    id IN (@firstId, @secondId, @thirdId);

If you wish to also order by the computed column, then add ORDER BY val to the end of the above query.

like image 106
Tim Biegeleisen Avatar answered Oct 11 '22 17:10

Tim Biegeleisen


You can use CASE like following.

SELECT 
       CASE 
              WHEN id= @firstId THEN 1 
              WHEN id=@secondId THEN 2 
              ELSE 3 
       END AS rn, 
       mycolumn 
FROM   mytable 
WHERE  id IN (@firstId, 
              @secondId, 
              @thirdId)

Another approach can be using DENSE_RANK if you have one record for each provided id and @firstId, @secondId & @thirdId are in ascending order.

SELECT DENSE_RANK() 
         OVER( 
           ORDER BY id) rn, 
       mycolumn 
FROM   mytable 
WHERE  id IN ( @firstId, @secondId, @thirdId ) 
like image 21
PSK Avatar answered Oct 11 '22 18:10

PSK