Как получить столбец с наименьшими значениями среди них

CREATE TABLE exmp_test ( id int, v1 int, v2 int, v3 int, v4 int ) SELECT * FROM exmp_test id v1 v2 v3 v4 1 2 4 6 7 1 4 77 3 8 

Я хочу добавить значение столбца [id] в значение (в зависимости от того, какое значение имеет наименьшее значение для v1, v2, v3, v4) для каждой строки.

В качестве примера, для первой строки значение [id] должно быть добавлено к v1 (поскольку оно имеет самое низкое значение). Для второй строки значение [id] должно быть добавлено к v3 (поскольку оно имеет самое низкое значение).

Как я могу написать SQL для этого?

Вы можете нормализовать таблицу в CTE (общее табличное выражение), а затем выбрать строку с минимальным значением. Основываясь на комментарии ниже вашего вопроса, я добавил приоритет для v1.

 ;with Normal as ( select id, v1 as value, 1 as prio from YourTable union all select id, v2, 2 as prio from YourTable union all select id, v3, 3 as prio from YourTable union all select id, v4, 4 as prio from YourTable ) select top 1 id, value from Normal where value = ( select min(value) from Normal ) order by prio 

Перечитав свой вопрос, рассмотрим наименьшее значение для каждой строки и добавим к нему поле id :

 update t1 set v1 = v1 + case when mincol = 1 then id else 0 end , v2 = v2 + case when mincol = 2 then id else 0 end , v3 = v3 + case when mincol = 3 then id else 0 end , v4 = v4 + case when mincol = 4 then id else 0 end from ( select id, v1, v2, v3, v4, case when v1 <= v2 and v1 <= v3 and v1 <= v4 then 1 when v2 <= v3 and v2 <= v4 then 2 when v3 <= v4 then 3 else 4 end as mincol from YourTable ) t1 

Вы можете сделать то же самое с помощью UVPIVOT

Данные испытаний

 declare @exmp_test table(id int, v1 int,v2 int,v3 int,v4 int) insert into @exmp_test select 1, 2 , 4 , 6, 7 union all select 1 , 4 , 77 , 3 , 8 union all select 2 , 4 , 16 , 1 , 8 

запрос

 ;with cte as(select row_number() over(order by id) as rn,t.v1 + t.v2 + t.v3 + t.v4 as sumallversions,t.* from @exmp_test t) ,unpvtcte as(select rn,id as versions,vals from (select rn,[v1],[v2],[v3],[v4] from cte)t unpivot (vals for id in([v1],[v2],[v3],[v4]))as unpvt) update @exmp_test set id = y.sumall from @exmp_test e join ( select c.id,c.id + x.minvals as sumall,c.sumallversions, x.minvals from cte c join(select rn,MIN(vals) minvals from unpvtcte group by rn)x on x.rn = c.rn) y on y.id = e.id and y.sumallversions = e.v1 + e.v2 + e.v3 + e.v4 

Вывод:

 id v1 v2 v3 v4 3 2 4 6 7 4 4 77 3 8 3 4 16 1 8 
Interesting Posts
Давайте будем гением компьютера.