如何将UNION更改为IN子句?

时间:2019-02-11 08:07:36

标签: sql sql-server sql-server-2017

我最多需要从同一张表中获取3条不同的记录,所以目前我正在做:

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

实际的SELECT部分包含20多个列,而FROM部分包含许多JOINs。第一列是一个常数,并且始终是固定的,具体取决于记录。我不知道会返回多少记录。可以是0到3条记录。

是否可以更改上述查询,以便它像这样使用IN

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

但是,如果我使用IN,如何将每个记录显式映射到固定常量?

3 个答案:

答案 0 :(得分:5)

您可以在一个查询中使用CASE表达式:

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

如果您还希望按计算所得的列进行排序,请在上述查询的末尾添加ORDER BY val

答案 1 :(得分:3)

您可以像下面这样使用CASE

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)

如果每个提供的ID都有一条记录,并且@ firstId,@ secondId和@thirdId以升序排列,则另一种方法可以使用DENSE_RANK

SELECT DENSE_RANK() 
         OVER( 
           ORDER BY id) rn, 
       mycolumn 
FROM   mytable 
WHERE  id IN ( @firstId, @secondId, @thirdId ) 

答案 2 :(得分:1)

为此,我建议使用一个表值构造函数:

select v.outputnum, my_column
from mytable t join
     (values (@firstid, 1),
             (@secondid, 2),
             (@thirdid, 3)
     ) v(id, outputnum)
     on t.id = v.id
order by v.outputnum;

我认为这比其他版本更简单,因为ID列表仅在查询中出现一次-因此,没有危险,查询的不同部分将不同步。