hacer sql subquery sum max

hacer - max count sql server 2008



Máx. De suma en SQL (7)

Esto funciona en Oracle, otras implementaciones pueden tener una sintaxis diferente para funciones analíticas (o carecerlas por completo):

select store , max(department) keep(dense_rank last order by sales) , max(sales) from ( ...query that generates your results... ) group by store

Tengo una lista de tiendas, departamentos dentro de las tiendas y ventas para cada departamento, de esa manera (creado usando max (ventas) en una subconsulta, pero eso no es terriblemente importante aquí, no creo):

toronto baskets 500 vancouver baskets 350 halifax baskets 100 toronto noodles 275 vancouver noodles 390 halifax noodles 120 halifax fish 200

Me gustaría solicitar el departamento de mayor venta en cada tienda. Los resultados deberían verse así:

toronto baskets 500 vancouver noodles 275 halifax fish 200

Cada vez que uso GROUP BY, incluye todos los listados de mi subconsulta. ¿Hay una buena manera de hacerlo sin una tabla temporal?


Esto funciona en Sql Server (2000 y más seguro)

SELECT a.Store, a.Department, a.Sales FROM temp a INNER JOIN (SELECT store, max(sales) as sales FROM temp GROUP BY Store) b ON a.Store = b.Store AND a.Sales = b.Sales;


Esto funcionará

Select Store, Department, Sales From yourTable A Where Sales = (Select Max(Sales) From YourTable Where Store = A.Store)


Esto funcionará en SQL Server sin tablas temporales:

SELECT Store, Department, Sales FROM (SELECT Store, Department, Sales, DENSE_RANK() OVER (PARTITION BY Store ORDER BY Sales DESC) AS Dense_Rank FROM Sales) A WHERE Dense_Rank = 1

DONDE "Ventas" = su consulta original


Esto funcionará en SQL Server, a partir de 2005:

with data as (select store, department, sales from <your query>), maxsales as (select store, sales = max(sales) from data group by store) select store, (select top 1 department from data where store = t.store and sales = t.sales order by [your criteria for ties]), sales from maxsales m

Supongo que solo desea mostrar 1 departamento en caso de empates, de ahí los primeros 1 y [su criterio de empate] para distinguir entre ellos.


Mis 2 soluciones para SQL 2005 están a continuación. Los otros que puedo ver hasta ahora pueden no devolver los datos correctos si dos de las cifras de ventas son las mismas. Eso depende de tus necesidades sin embargo.

El primero usa la función Row_Number (), todas las filas se clasifican desde las ventas más bajas hasta las más altas (luego algunas reglas de desempate). Luego, se elige el rango más alto por tienda para obtener el resultado.

Puede intentar agregar una cláusula Partion By a la función Row_Number (vea BOL) y / o investigar utilizando una combinación interna en lugar de una cláusula "in".

El segundo, tomar prestado de la idea de Turnkey, los clasifica de nuevo, pero las particiones por tienda, para que podamos elegir el primero clasificado. Dense_Rank posiblemente dará dos filas idénticas del mismo rango, por lo que si la tienda y el departamento no fueran únicos, podría devolver dos filas. Con Row_number, el número es único en la partición.

Algunas cosas a tener en cuenta es que esto puede ser lento, pero sería más rápido para la mayoría de los conjuntos de datos que la sub consulta en una de las otras soluciones. En esa solución, la consulta debería ejecutarse una vez por fila (incluida la clasificación, etc.), lo que podría generar muchas consultas.

Otras consultas: seleccione las ventas máximas por tienda y devuelva los datos de esa manera, devuelva filas duplicadas para una tienda si dos departamentos tienen las mismas ventas. La última consulta muestra esto.

DECLARE @tbl as TABLE (store varchar(20), department varchar(20), sales int) INSERT INTO @tbl VALUES (''Toronto'', ''Baskets'', 500) INSERT INTO @tbl VALUES (''Toronto'', ''Noodles'', 500) INSERT INTO @tbl VALUES (''Toronto'', ''Fish'', 300) INSERT INTO @tbl VALUES (''Halifax'', ''Fish'', 300) INSERT INTO @tbl VALUES (''Halifax'', ''Baskets'', 200) -- Expect Toronto/Noodles/500 and Halifax/Fish/300 ;WITH ranked AS -- Rank the rows by sales from 1 to x ( SELECT ROW_NUMBER() OVER (ORDER BY sales, store, department) as ''rank'', store, department, sales FROM @tbl ) SELECT store, department, sales FROM ranked WHERE rank in ( SELECT max(rank) -- chose the highest ranked per store FROM ranked GROUP BY store ) -- Another way SELECT store, department, sales FROM ( SELECT DENSE_RANK() OVER (PARTITION BY store ORDER BY sales desc, store desc, department desc) as ''rank'', store, department, sales FROM @tbl ) tbl WHERE rank = 1 -- This will bring back 2 rows for Toronto select tbl.store, department, sales from @tbl tbl join ( select store, max(sales) as maxSales from @tbl group by store ) tempTable on tempTable.store = tbl.store and tempTable.maxSales = tbl.sales


Quizás esto podría funcionar. Aunque aún no lo he probado, podría haber una mejor solución ...

select yourTable.store, dept, sales from yourTable join ( select store, max(sales) as maxSales from yourTable group by store ) tempTable on tempTable.store = yourTable.store and tempTable.maxSales = yourTable.sales