What's the best way to select the minimum value from several columns?

后端 未结 19 2058
余生分开走
余生分开走 2020-11-27 02:47

Given the following table in SQL Server 2005:

ID   Col1   Col2   Col3
--   ----   ----   ----
1       3     34     76  
2      32    976     24
3       7             


        
相关标签:
19条回答
  • 2020-11-27 03:45

    If you use SQL 2005 you can do something neat like this:

    ;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
    

    This way you don't get lost in so many operators :)

    However, this could be slower than the other choice.

    It's your choice...

    0 讨论(0)
  • 2020-11-27 03:47

    You could also do this with a union query. As the number of columns increase, you would need to modify the query, but at least it would be a straight forward modification.

    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
    
    0 讨论(0)
  • 2020-11-27 03:48

    There are likely to be many ways to accomplish this. My suggestion is to use Case/When to do it. With 3 columns, it's not too bad.

    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
    
    0 讨论(0)
  • 2020-11-27 03:48

    A little twist on the union query:

    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
    
    0 讨论(0)
  • 2020-11-27 03:49

    Using CROSS APPLY:

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

    SQL Fiddle

    0 讨论(0)
  • 2020-11-27 03:50

    You can use the "brute force" approach with a twist:

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

    When the first when condition fails it guarantees that Col1 is not the smallest value therefore you can eliminate it from rest of the conditions. Likewise for subsequent conditions. For five columns your query becomes:

    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]
    

    Note that if there is a tie between two or more columns then <= ensures that we exit the CASE statement as early as possible.

    0 讨论(0)
提交回复
热议问题