multiple español ejemplos columns all sql sql-server tsql

español - sql max group by



SQL MAX de columnas múltiples? (20)

¿Cómo devuelves 1 valor por fila del máximo de varias columnas:

Nombre de la tabla

[Number, Date1, Date2, Date3, Cost]

Necesito devolver algo como esto:

[Number, Most_Recent_Date, Cost]

¿Consulta?


Aquí hay otra buena solución para la funcionalidad Max usando T-SQL y SQL Server.

SELECT [Other Fields], (SELECT Max(v) FROM (VALUES (date1), (date2), (date3),...) AS value(v)) as [MaxDate] FROM [YourTableName]


Aquí hay una buena solución:

CREATE function [dbo].[inLineMax] (@v1 float,@v2 float,@v3 float,@v4 float) returns float as begin declare @val float set @val = 0 declare @TableVal table (value float ) insert into @TableVal select @v1 insert into @TableVal select @v2 insert into @TableVal select @v3 insert into @TableVal select @v4 select @val= max(value) from @TableVal return @val end



Bueno, puedes usar la sentencia CASE:

SELECT CASE WHEN Date1 >= Date2 AND Date1 >= Date3 THEN Date1 WHEN Date2 >= Date1 AND Date2 >= Date3 THEN Date2 WHEN Date3 >= Date1 AND Date3 >= Date2 THEN Date3 ELSE Date1 END AS MostRecentDate

[Para Microsoft SQL Server 2008 y versiones posteriores, puede considerar la respuesta más simple de Sven a continuación.]


Cualquiera de las dos muestras siguientes funcionará:

SELECT MAX(date_columns) AS max_date FROM ( (SELECT date1 AS date_columns FROM data_table ) UNION ( SELECT date2 AS date_columns FROM data_table ) UNION ( SELECT date3 AS date_columns FROM data_table ) ) AS date_query

El segundo es un complemento a lassevk''s respuesta lassevk''s .

SELECT MAX(MostRecentDate) FROM ( SELECT CASE WHEN date1 >= date2 AND date1 >= date3 THEN date1 WHEN date2 >= date1 AND date2 >= date3 THEN date2 WHEN date3 >= date1 AND date3 >= date2 THEN date3 ELSE date1 END AS MostRecentDate FROM data_table ) AS date_query


Desafortunadamente, la respuesta de Lasse , aunque aparentemente obvia, tiene un defecto crucial. No puede manejar valores NULL. Cualquier valor NULL único hace que se devuelva Date1. Desafortunadamente, cualquier intento de solucionar ese problema tiende a ser extremadamente complicado y no se ajusta muy bien a 4 o más valores.

La primera respuesta de databyss se veía (y es) buena. Sin embargo, no estaba claro si la respuesta se extrapolaría fácilmente a 3 valores de una combinación de varias tablas en lugar de los 3 valores más simples de una sola tabla. Quería evitar convertir una consulta de este tipo en una subconsulta para obtener el máximo de 3 columnas, y también estaba bastante seguro de que la excelente idea de databyss se podría limpiar un poco.

Así que sin más preámbulos, aquí está mi solución (derivada de la idea de databyss).
Utiliza las combinaciones de selección de combinaciones cruzadas para simular el efecto de una combinación de varias tablas. Lo importante a tener en cuenta es que todos los alias necesarios se transfieren correctamente (lo que no siempre es así) y esto mantiene el patrón bastante simple y bastante escalable a través de columnas adicionales.

DECLARE @v1 INT , @v2 INT , @v3 INT --SET @v1 = 1 --Comment out SET statements to experiment with --various combinations of NULL values SET @v2 = 2 SET @v3 = 3 SELECT ( SELECT MAX(Vals) FROM ( SELECT v1 AS Vals UNION SELECT v2 UNION SELECT v3 ) tmp WHERE Vals IS NOT NULL -- This eliminates NULL warning ) AS MaxVal FROM ( SELECT @v1 AS v1 ) t1 CROSS JOIN ( SELECT @v2 AS v2 ) t2 CROSS JOIN ( SELECT @v3 AS v3 ) t3


Desde SQL Server 2012 podemos utilizar IIF .

DECLARE @Date1 DATE=''2014-07-03''; DECLARE @Date2 DATE=''2014-07-04''; DECLARE @Date3 DATE=''2014-07-05''; SELECT IIF(@Date1>@Date2, IIF(@Date1>@Date3,@Date1,@Date3), IIF(@Date2>@Date3,@Date2,@Date3)) AS MostRecentDate


Existen 3 métodos más en los que UNPIVOT (1) es el más rápido por el momento, seguido de Unpivot simulado (3) que es mucho más lento que (1) pero aún más rápido que (2)

CREATE TABLE dates ( number INT PRIMARY KEY , date1 DATETIME , date2 DATETIME , date3 DATETIME , cost INT ) INSERT INTO dates VALUES ( 1, ''1/1/2008'', ''2/4/2008'', ''3/1/2008'', 10 ) INSERT INTO dates VALUES ( 2, ''1/2/2008'', ''2/3/2008'', ''3/3/2008'', 20 ) INSERT INTO dates VALUES ( 3, ''1/3/2008'', ''2/2/2008'', ''3/2/2008'', 30 ) INSERT INTO dates VALUES ( 4, ''1/4/2008'', ''2/1/2008'', ''3/4/2008'', 40 ) GO

Solución 1 ( UNPIVOT )

SELECT number , MAX(dDate) maxDate , cost FROM dates UNPIVOT ( dDate FOR nDate IN ( Date1, Date2, Date3 ) ) as u GROUP BY number , cost GO

Solución 2 (Sub consulta por fila)

SELECT number , ( SELECT MAX(dDate) maxDate FROM ( SELECT d.date1 AS dDate UNION SELECT d.date2 UNION SELECT d.date3 ) a ) MaxDate , Cost FROM dates d GO

Solución 3 ( UNPIVOT simulado)

;WITH maxD AS ( SELECT number , MAX(CASE rn WHEN 1 THEN Date1 WHEN 2 THEN date2 ELSE date3 END) AS maxDate FROM dates a CROSS JOIN ( SELECT 1 AS rn UNION SELECT 2 UNION SELECT 3 ) b GROUP BY Number ) SELECT dates.number , maxD.maxDate , dates.cost FROM dates INNER JOIN MaxD ON dates.number = maxD.number GO DROP TABLE dates GO


La función escalar causa todo tipo de problemas de rendimiento, por lo que es mejor envolver la lógica en una función de valor de tabla en línea si es posible. Esta es la función que utilicé para reemplazar algunas funciones definidas por el usuario que seleccionaron las fechas mín. / Máx. De una lista de hasta diez fechas. Cuando se probó en mi conjunto de datos de 1 millón de filas, la función escalar tomó más de 15 minutos antes de que eliminara la consulta, el Inline TVF tomó 1 minuto, que es la misma cantidad de tiempo que para seleccionar el conjunto de resultados en una tabla temporal. Para usar esta llamada, llame a la función desde una subconsulta en SELECT o CROSS APPLY.

CREATE FUNCTION dbo.Get_Min_Max_Date ( @Date1 datetime, @Date2 datetime, @Date3 datetime, @Date4 datetime, @Date5 datetime, @Date6 datetime, @Date7 datetime, @Date8 datetime, @Date9 datetime, @Date10 datetime ) RETURNS TABLE AS RETURN ( SELECT Max(DateValue) Max_Date, Min(DateValue) Min_Date FROM ( VALUES (@Date1), (@Date2), (@Date3), (@Date4), (@Date5), (@Date6), (@Date7), (@Date8), (@Date9), (@Date10) ) AS Dates(DateValue) )


No sé si está en SQL, etc ... en la ayuda de M $ ACCESS hay una función llamada MAXA(Value1;Value2;...) que se supone que lo hace.

La esperanza puede ayudar a alguien.

PD: Los valores pueden ser columnas o calculados, etc.


Otra forma de usar CASO CUANDO

SELECT CASE true WHEN max(row1) >= max(row2) THEN CASE true WHEN max(row1) >= max(row3) THEN max(row1) ELSE max(row3) end ELSE CASE true WHEN max(row2) >= max(row3) THEN max(row2) ELSE max(row3) END END FROM yourTable


Para T-SQL (MSSQL 2008+)

SELECT (SELECT MAX(MyMaxName) FROM ( VALUES (MAX(iSortCode)), (MAX(Field2)) ) MyAlias(MyMaxName) ) FROM MyTable1


Por favor intente usar UNPIVOT :

SELECT MAX(MaxDt) MaxDt FROM tbl UNPIVOT (MaxDt FOR E IN (Date1, Date2, Date3) )AS unpvt;


Problema: elija el valor de tasa mínima otorgado a una entidad Requisitos: las tasas de agencia pueden ser nulas

[MinRateValue] = CASE WHEN ISNULL(FitchRating.RatingValue, 100) < = ISNULL(MoodyRating.RatingValue, 99) AND ISNULL(FitchRating.RatingValue, 100) < = ISNULL(StandardPoorsRating.RatingValue, 99) THEN FitchgAgency.RatingAgencyName WHEN ISNULL(MoodyRating.RatingValue, 100) < = ISNULL(StandardPoorsRating.RatingValue , 99) THEN MoodyAgency.RatingAgencyName ELSE ISNULL(StandardPoorsRating.RatingValue, ''N/A'') END

Inspirado por share de


Puede crear una función donde pase las fechas y luego agregar la función a la instrucción de selección como se muestra a continuación. Seleccione Número, dbo.fxMost_Recent_Date (Date1, Date2, Date3), Cost

create FUNCTION fxMost_Recent_Date

(@ Date1 smalldatetime, @ Date2 smalldatetime, @ Date3 smalldatetime) DEVOLUCIONES smalldatetime COMO COMENZAR A DECLARAR @Resultar smalldatetime

declare @MostRecent smalldatetime set @MostRecent=''1/1/1900'' if @Date1>@MostRecent begin set @MostRecent=@Date1 end if @Date2>@MostRecent begin set @MostRecent=@Date2 end if @Date3>@MostRecent begin set @MostRecent=@Date3 end RETURN @MostRecent

FIN


Si está utilizando SQL Server 2005, puede usar la función UNPIVOT. Aquí hay un ejemplo completo:

create table dates ( number int, date1 datetime, date2 datetime, date3 datetime ) insert into dates values (1, ''1/1/2008'', ''2/4/2008'', ''3/1/2008'') insert into dates values (1, ''1/2/2008'', ''2/3/2008'', ''3/3/2008'') insert into dates values (1, ''1/3/2008'', ''2/2/2008'', ''3/2/2008'') insert into dates values (1, ''1/4/2008'', ''2/1/2008'', ''3/4/2008'') select max(dateMaxes) from ( select (select max(date1) from dates) date1max, (select max(date2) from dates) date2max, (select max(date3) from dates) date3max ) myTable unpivot (dateMaxes For fieldName In (date1max, date2max, date3max)) as tblPivot drop table dates


Si estás usando MySQL, puedes usar

SELECT GREATEST(col1, col2 ...) FROM table


Usando CROSS APPLY (para 2005+) ....

SELECT MostRecentDate FROM SourceTable CROSS APPLY (SELECT MAX(d) MostRecentDate FROM (VALUES (Date1), (Date2), (Date3)) AS a(d)) md


DECLARE @TableName TABLE (Number INT, Date1 DATETIME, Date2 DATETIME, Date3 DATETIME, Cost MONEY) INSERT INTO @TableName SELECT 1, ''20000101'', ''20010101'',''20020101'',100 UNION ALL SELECT 2, ''20000101'', ''19900101'',''19980101'',99 SELECT Number, Cost , (SELECT MAX([Date]) FROM (SELECT Date1 AS [Date] UNION ALL SELECT Date2 UNION ALL SELECT Date3 ) D ) [Most Recent Date] FROM @TableName


SELECT CASE WHEN Date1 >= Date2 AND Date1 >= Date3 THEN Date1 WHEN Date2 >= Date3 THEN Date2 ELSE Date3 END AS MostRecentDate

Esto es un poco más fácil de escribir y omite los pasos de evaluación a medida que la declaración del caso se evalúa en orden.