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