Как заменить UNION на предложение IN? - PullRequest
0 голосов
/ 11 февраля 2019

Мне нужно получить максимум 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 голосов
/ 11 февраля 2019

Вы можете использовать выражение 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 в конец вышеуказанного запроса.

0 голосов
/ 11 февраля 2019

Я бы порекомендовал для этой цели конструктор с табличным значением:

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;

Я думаю, что это проще, чем в других версиях, потому что список идентификаторов присутствует только один раз в запросе - так что никакой опасностииз разных частей запроса не синхронизированы.

0 голосов
/ 11 февраля 2019

Вы можете использовать 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)

Другой подход может использовать DENSE_RANK, если у вас есть одна запись для каждого предоставленного идентификатора, а @firstId, @secondId & @thirdId находятся в порядке возрастаниязаказ.

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