2009-10-06 19 views
7

Imagine que tengo una tabla que muestra las ventas de Acme Widgets y dónde se vendieron. Es bastante fácil producir un informe que agrupe las ventas por país. Es bastante fácil encontrar los 10 primeros. Pero lo que me gustaría es mostrar los 10 primeros, y luego tener una última fila diciendo Otro. Por ejemplo,SQL para producir Top 10 y Otro

Ctry | Sales 
============= 
GB | 100 
US | 80 
ES | 60 
... 
IT | 10 
Other | 50 

He estado buscando durante mucho tiempo, pero parece que no puede encontrar ninguna ayuda que me lleva más allá de la norma superior 10.

TIA

+2

¿Qué sabor de SQL estás usando? Diferentes productos tendrán diferentes soluciones – APC

Respuesta

5

me trataron algunos de los otras soluciones aquí, sin embargo, parecen estar ligeramente fuera de servicio, o el orden no fue del todo correcto.

Mi intento de solución de Microsoft SQL Server parece funcionar correctamente:

SELECT Ctry, Sales FROM 
(
    SELECT TOP 2 
     Ctry, 
     SUM(Sales) AS Sales 
    FROM 
     Table1 
    GROUP BY 
     Ctry 
    ORDER BY 
     Sales DESC 
) AS Q1 
UNION ALL 
SELECT 
    'Other' AS Ctry, 
    SUM(Sales) AS Sales 
FROM 
    Table1 
WHERE 
    Ctry NOT IN (SELECT TOP 2 
      Ctry 
       FROM 
       Table1 
       GROUP BY 
      Ctry 
       ORDER BY 
      SUM(Sales) DESC) 

Tenga en cuenta que en mi ejemplo, yo sólo estoy usando TOP 2 en lugar de TOP 10. Esto es simplemente debido a mi datos de prueba siendo bastante más limitado. Puede sustituir fácilmente el 2 por un 10 en sus propios datos.

Aquí está la secuencia de comandos SQL para crear la tabla:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
SET ANSI_PADDING ON 
GO 
CREATE TABLE [dbo].[Table1](
    [Ctry] [varchar](50) NOT NULL, 
    [Sales] [float] NOT NULL 
) ON [PRIMARY] 

GO 
SET ANSI_PADDING OFF 

Y mis datos tiene el siguiente aspecto:

GB 10 
GB 21.2 
GB 34 
GB 16.75 
US 10 
US 11 
US 56.43 
FR 18.54 
FR 98.58 
WE 44.33 
WE 11.54 
WE 89.21 
KR 10 
PO 10 
DE 10 

Tenga en cuenta que el resultado de la consulta se ordena correctamente por el agregado de valor de las ventas y no el código de país alfabético, y que la categoría "Otro" siempre es la última, incluso si su agregado de valor de venta ordinariamente lo empujaría a la parte superior de la lista.

No digo que esta es la mejor solución (léase: la más óptima), sin embargo, para el conjunto de datos que proporcioné, parece funcionar bastante bien.

0

Unión entre los diez primeros con una combinación externa Únase a los diez primeros con la tabla para agregar el resto.

no tengo acceso a SQL aquí, pero voy a Hazzard una conjetura:

select top (10) Ctry, sales from table1 
union all 
select 'other', sum(sales) 
from table1 
left outer join (select top (10) Ctry, sales from table1) as table2 
on table2.Ctry = table2.Ctry 
where table2.ctry = null 
group by table1.Ctry 

Por supuesto, si se trata de una parte superior que cambia rápidamente (10) a continuación, ya sea bloqueo o mantener una copia de la arriba (10) para la duración de la consulta.

0

En seudo SQL: seleccionar el orden de los 10 por las ventas UNIÓN seleccione 'Otro', SUM (ventas), donde Ctry no en (SELECT TOP 10 como la de arriba)

1
SELECT Ctry, sum(Sales) Sales 
FROM (SELECT COALESCE(T2.Ctry, 'OTHER') Ctry, T1.Sales 
     FROM (SELECT Ctry, sum(Sales) Sales 
       FROM Table1 
       GROUP BY Ctry) T1 
      LEFT JOIN 
      (SELECT TOP 10 Ctry, sum(sales) Sales 
       FROM Table1 
       GROUP BY Ctry) T2 
      on T1.Ctry = T2.Ctry 
    ) T 
GROUP BY Ctry 
0

Tenga en cuenta que, según su uso (y el volumen/restricciones de la base de datos), puede obtener los mismos resultados utilizando el código de la aplicación (python, nodo, C#, java, etc.). Sure it will depend on your use-case pero bueno, es posible.

que terminé haciendo esto en C#, por ejemplo:

// Mockup Class that has a CATEGORY and it's VOLUME 
class YourModel { string category; double volume; } 


List<YourModel> groupedList = wholeList.Take (5).ToList(); 
groupedList.Add (new YourModel() 
     { 
      category = "Others", 
      volume = tempChartData.Skip (5).Select (t => t.qtd).Sum() 
     }); 

Negación

entiendo que esta es la pregunta marcada con una "Sólo SQL", pero puede haber otras personas como yo a cabo allí quién puede utilizar la capa de aplicación en lugar de confiar únicamente en SQL para hacerlo realidad. Solo intento mostrarle a la gente otras formas de hacer lo mismo, eso podría ser útil. Incluso si esto se reduce al olvido, sé que alguien estará feliz de leer esto porque se les enseñó a usar cada herramienta para que sea lo mejor, y piensan "fuera de la caja".

Cuestiones relacionadas