从多列中选择最小值的最佳方法是什么？

``````ID   Col1   Col2   Col3
--   ----   ----   ----
1       3     34     76
2      32    976     24
3       7    235      3
4     245      1    792
``````

``````ID   Col1   Col2   Col3  TheMin
--   ----   ----   ----  ------
1       3     34     76       3
2      32    976     24      24
3       7    235      3       3
4     245      1    792       1
``````

``````with cte (ID, Col1, Col2, Col3)
as
(
select ID, Col1, Col2, Col3
from TestTable
)
select cte.ID, Col1, Col2, Col3, TheMin from cte
join
(
select
ID, min(Amount) as TheMin
from
cte
UNPIVOT (Amount for AmountCol in (Col1, Col2, Col3)) as unpvt
group by ID
) as minValues
on cte.ID = minValues.ID
``````

19 个答案:

``````Select Id,
Case When Col1 < Col2 And Col1 < Col3 Then Col1
When Col2 < Col1 And Col2 < Col3 Then Col2
Else Col3
End As TheMin
From   YourTableNameHere
``````

``````SELECT ID, Col1, Col2, Col3, MinValue
FROM YourTable
CROSS APPLY (SELECT MIN(d) MinValue FROM (VALUES (Col1), (Col2), (Col3)) AS a(d)) A
``````

``````SELECT ID, Col1, Col2, Col3,
(SELECT MIN(Col) FROM (VALUES (Col1), (Col2), (Col3)) AS X(Col)) AS TheMin
FROM Table
``````

``````ID    Col    Val
--    ---    ---
1      1      3
1      2     34
1      3     76

2      1     32
2      2    976
2      3     24

3      1      7
3      2    235
3      3      3

4      1    245
4      2      1
4      3    792
``````

`ID/Col`为主键（可能`Col`作为额外键，具体取决于您的需要）。然后，您的查询变为简单的`select min(val) from tbl`，您仍然可以在其他查​​询中使用`where col = 2`单独处理各个“旧列”。如果“旧列”的数量增加，这也可以轻松扩展。

``````ID   Col1   Col2   Col3   MinVal
--   ----   ----   ----   ------
1      3     34     76        3
2     32    976     24       24
3      7    235      3        3
4    245      1    792        1
``````

``````SELECT CASE
WHEN Col1 <= Col2 AND Col1 <= Col3 THEN Col1
WHEN                  Col2 <= Col3 THEN Col2
ELSE                                    Col3
END AS [Min Value] FROM [Your Table]
``````

``````SELECT CASE
WHEN Col1 <= Col2 AND Col1 <= Col3 AND Col1 <= Col4 AND Col1 <= Col5 THEN Col1
WHEN                  Col2 <= Col3 AND Col2 <= Col4 AND Col2 <= Col5 THEN Col2
WHEN                                   Col3 <= Col4 AND Col3 <= Col5 THEN Col3
WHEN                                                    Col4 <= Col5 THEN Col4
ELSE                                                                      Col5
END AS [Min Value] FROM [Your Table]
``````

``````create function f_min_int(@a as int, @b as int)
returns int
as
begin
return case when @a < @b then @a else coalesce(@b,@a) end
end
``````

``````select col1, col2, col3, dbo.f_min_int(dbo.f_min_int(col1,col2),col3)
``````

``````select col1, col2, col3, col4, col5,
dbo.f_min_int(dbo.f_min_int(dbo.f_min_int(dbo.f_min_int(col1,col2),col3),col4),col5)
``````

``````Select T.Id, T.Col1, T.Col2, T.Col3, A.TheMin
From   YourTable T
Inner Join (
Select A.Id, Min(A.Col1) As TheMin
From   (
Select Id, Col1
From   YourTable

Union All

Select Id, Col2
From   YourTable

Union All

Select Id, Col3
From   YourTable
) As A
Group By A.Id
) As A
On T.Id = A.Id
``````

``````select least(col1, col2, col3) FROM yourtable
``````

`````` select case when col1 <= col2 and col1 <= col3 then col1
case when col2 <= col1 and col2 <= col3 then col2
case when col3 <= col1 and col3 <= col2 then col3
as 'TheMin'
end

from Table T
``````

...因为min（）仅适用于一列，而不适用于列。

this questionthis question试图回答这个问题。

``````select *,
case when column1 < columnl2 And column1 < column3 then column1
when columnl2 < column1 And columnl2 < column3 then columnl2
else column3
end As minValue
from   tbl_example
``````

``````SELECT [ID],
(
SELECT MIN([value].[MinValue])
FROM
(
VALUES
([Col1]),
([Col1]),
([Col2]),
([Col3])
) AS [value] ([MinValue])
) AS [MinValue]
FROM Table;
``````

``````;WITH    res
AS ( SELECT   t.YourID ,
CAST(( SELECT   Col1 AS c01 ,
Col2 AS c02 ,
Col3 AS c03 ,
Col4 AS c04 ,
Col5 AS c05
FROM     YourTable AS cols
WHERE    YourID = t.YourID
FOR
XML AUTO ,
ELEMENTS
) AS XML) AS colslist
FROM     YourTable AS t
)
SELECT  YourID ,
colslist.query('for \$c in //cols return min(data(\$c/*))').value('.',
'real') AS YourMin ,
colslist.query('for \$c in //cols return avg(data(\$c/*))').value('.',
'real') AS YourAvg ,
colslist.query('for \$c in //cols return max(data(\$c/*))').value('.',
'real') AS YourMax
FROM    res
``````

min（i，j）=（i + j）/ 2 - abs（i-j）/ 2

``````--==================== this gets minimums and global min
if object_id('tempdb..#temp1') is not null
drop table #temp1
if object_id('tempdb..#temp2') is not null
drop table #temp2

select r.recordid ,  r.ReferenceNumber, i.InventionTitle, RecordDate, i.ReceivedDate
, min(fi.uploaddate) [Min File Upload], min(fi.CorrespondenceDate) [Min File Correspondence]
into #temp1
from record r
join Invention i on i.inventionid = r.recordid
left join LnkRecordFile lrf on lrf.recordid = r.recordid
left join fileinformation fi on fi.fileid = lrf.fileid
where r.recorddate > '2015-05-26'
group by  r.recordid, recorddate, i.ReceivedDate,
r.ReferenceNumber, i.InventionTitle

select recordid, recorddate [min date]
into #temp2
from #temp1

update #temp2
set [min date] = ReceivedDate
from #temp1 t1 join #temp2 t2 on t1.recordid = t2.recordid
where t1.ReceivedDate < [min date] and  t1.ReceivedDate > '2001-01-01'

update #temp2
set [min date] = t1.[Min File Upload]
from #temp1 t1 join #temp2 t2 on t1.recordid = t2.recordid
where t1.[Min File Upload] < [min date] and  t1.[Min File Upload] > '2001-01-01'

update #temp2
set [min date] = t1.[Min File Correspondence]
from #temp1 t1 join #temp2 t2 on t1.recordid = t2.recordid
where t1.[Min File Correspondence] < [min date] and t1.[Min File Correspondence] > '2001-01-01'

select t1.*, t2.[min date] [LOWEST DATE]
from #temp1 t1 join #temp2 t2 on t1.recordid = t2.recordid
order by t1.recordid
``````

``````DECLARE @Foo TABLE (ID INT, Col1 INT, Col2 INT, Col3 INT)

INSERT @Foo (ID, Col1, Col2, Col3)
VALUES
(1, 3, 34, 76),
(2, 32, 976, 24),
(3, 7, 235, 3),
(4, 245, 1, 792)

SELECT
ID,
Col1,
Col2,
Col3,
(
SELECT MIN(T.Col)
FROM
(
SELECT Foo.Col1 AS Col UNION ALL
SELECT Foo.Col2 AS Col UNION ALL
SELECT Foo.Col3 AS Col
) AS T
) AS TheMin
FROM
@Foo AS Foo
``````

``````select case when 0 in (PAGE1STATUS ,PAGE2STATUS ,PAGE3STATUS,
PAGE4STATUS,PAGE5STATUS ,PAGE6STATUS) then 0 else 1 end
FROM CUSTOMERS_FORMS
``````

``````CREATE TABLE #tempTable (ID int, columnName varchar(20), dataValue int)

INSERT INTO #tempTable
SELECT ID, 'Col1', Col1
FROM sourceTable
WHERE Col1 IS NOT NULL
INSERT INTO #tempTable
SELECT ID, 'Col2', Col2
FROM sourceTable
WHERE Col2 IS NOT NULL
INSERT INTO #tempTable
SELECT ID, 'Col3', Col3
FROM sourceTable
WHERE Col3 IS NOT NULL

SELECT ID
, min(dataValue) AS 'Min'
, max(dataValue) AS 'Max'
, max(dataValue) - min(dataValue) AS 'Diff'
FROM #tempTable
GROUP BY ID
``````