2011-01-18 10 views

risposta

1

È possibile utilizzare MAX in una sotto-query

+3

Quindi show t lui pubblico _ come_. – SQB

20

No. Ma una query secondaria può accedere alle colonne dalla query esterna in modo da poter aggiungere una query secondaria UNION ALL alle colonne di interesse come tabella derivata, quindi selezionare il max da quello.

SELECT *, 
     (SELECT MAX(c) FROM 
        (SELECT number AS c 
        UNION ALL 
        SELECT status) T) AS GreatestNumberOrStatus 
FROM master..spt_values 

o una versione un po 'più conciso come siete su 2008.

SELECT *, 
     (SELECT MAX(c) FROM (VALUES(number),(status)) T (c)) AS Greatest 
FROM master..spt_values 
+2

+1, sebbene sia meno efficiente di una serie di istruzioni 'CASE'. – Quassnoi

+0

Concordato ma non è catastroficamente inefficiente e di facile manutenzione se il numero di colonne è elevato. –

+0

"è possibile aggiungere una query secondaria UNIONE TUTTE le colonne di interesse come tabella derivata" - potrebbe fare lo stesso utilizzando un CTE. – onedaywhen

5

Per questo, ho creato una funzione scalare come segue:

CREATE FUNCTION [dbo].[MaxOrNull](@val1 int, @val2 int) 
returns int 
as 
begin 
    if @val1 >= @val2 RETURN @val1 
    if @val1 < @val2 RETURN @val2 

    RETURN NULL 
end 

E' la soluzione più elegante e può essere utilizzato ovunque nel codice SQL.

+0

Non sono sicuro di aver mai visto prima le parole funzione scalare ed elegante nella stessa frase! Come utilizzerebbe l'OP per calcolare "GREATEST (col1, col2, col3, col4, col5, col6)" ad esempio? Non avrebbe bisogno di molte permutazioni? Modifica: In realtà, puoi semplicemente nidificare le chiamate, ovviamente in questo caso in cui le permutazioni crescono è il diverso scenario in cui si desidera ordinare attraverso le colonne. –

+0

Bene @ Martin, a volte ci vuole uno spostamento del punto di vista per vedere l'eleganza. Hard coding SQL disordinato dappertutto come la risposta verbosa nella risposta superiore ^^^ sopra è semplicemente folle. Hai risposto alla tua seconda domanda. Lo stesso vale per C++ o C#. – IamIC

+2

Un allungamento per me per darti +1. Ma questo è l'approccio che ho usato prima di SQL 2008, in preferenza su select-max-union annidato. La funzione che uso normalmente è più concisa 'create function dbo.greater (@a int, @b int) restituisce int come start return case quando @a> = isnull (@ b, @ a) then @a else @b end end ' – RichardTheKiwi

2

mi sento di raccomandare la seguente soluzione:

SELECT (CASE WHEN t.createdt < t.changedt THEN t.changedt ELSE t.created END) AS ChgDate 
    FROM table t 
1

Una possibile soluzione:

Create FUNCTION [dbo].[MaxOf] 
    (
     @val1 INT =0, 
     @val2 INT=0 , 
     @val3 INT =0, 
     @val4 INT =0, 
     @val5 INT =0, 
     @val6 INT =0, 
     @val7 INT =0, 
     @val8 INT =0, 
     @val9 INT =0, 
     @val10 INT =0, 
     @val11 INT =0, 
     @val12 INT =0, 
     @val13 INT =0, 
     @val14 INT =0, 
     @val15 INT =0, 
     @val16 INT =0, 
     @val17 INT =0, 
     @val18 INT =0, 
     @val19 INT =0, 
     @val20 INT =0) 
     --OUTPUT 
    RETURNS INT WITH SCHEMABINDING 
AS 
    BEGIN 
     DECLARE @MAX AS INT ; 
     SET @MAX=0 
     IF isnull(@val1,0)> isnull(@MAX,0) SET @MAX=isnull(@val1,0) 
     IF isnull(@val2,0)> isnull(@MAX,0) SET @MAX=isnull(@val2,0) 
     IF isnull(@val3,0)> isnull(@MAX,0) SET @MAX=isnull(@val3,0) 
     IF isnull(@val4,0)> isnull(@MAX,0) SET @MAX=isnull(@val4,0) 
     IF isnull(@val5,0)> isnull(@MAX,0) SET @MAX=isnull(@val5,0) 
     IF isnull(@val6,0)> isnull(@MAX,0) SET @MAX=isnull(@val6,0) 
     IF isnull(@val7,0)> isnull(@MAX,0) SET @MAX=isnull(@val7,0) 
     IF isnull(@val8,0)> isnull(@MAX,0) SET @MAX=isnull(@val8,0) 
     IF isnull(@val9,0)> isnull(@MAX,0) SET @MAX=isnull(@val9,0) 
     IF isnull(@val10,0)> isnull(@MAX,0) SET @MAX=isnull(@val10,0) 
     IF isnull(@val11,0)> isnull(@MAX,0) SET @MAX=isnull(@val11,0) 
     IF isnull(@val12,0)> isnull(@MAX,0) SET @MAX=isnull(@val12,0) 
     IF isnull(@val13,0)> isnull(@MAX,0) SET @MAX=isnull(@val13,0) 
     IF isnull(@val14,0)> isnull(@MAX,0) SET @MAX=isnull(@val14,0) 
     IF isnull(@val15,0)> isnull(@MAX,0) SET @MAX=isnull(@val15,0) 
     IF isnull(@val16,0)> isnull(@MAX,0) SET @MAX=isnull(@val16,0) 
     IF isnull(@val17,0)> isnull(@MAX,0) SET @MAX=isnull(@val17,0) 
     IF isnull(@val18,0)> isnull(@MAX,0) SET @MAX=isnull(@val18,0) 
     IF isnull(@val19,0)> isnull(@MAX,0) SET @MAX=isnull(@val19,0) 
     IF isnull(@val20,0)> isnull(@MAX,0) SET @MAX=isnull(@val20,0) 

     RETURN @MAX ; 
    END 

e la chiamata sarebbe

SELECT dbo.MaxOf (2,3,4,0,0,0,0,200,8,0,0,0,0,0,0,0,0,0,0,0) 
Problemi correlati