2009-10-06 13 views
7

Immaginate di avere una tabella che mostra le vendite di Acme Widget e dove sono stati venduti. È abbastanza facile produrre un report che raggruppa le vendite per Paese. È abbastanza facile trovare la top 10. Ma quello che mi piacerebbe è mostrare i primi 10, e poi avere una riga finale che dice Altro. Ad esempio,SQL per produrre Top 10 e Altro

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

ho cercato per secoli, ma non riesco a trovare alcun aiuto che mi porta oltre lo standard top 10.

TIA

+2

Quale sapore di SQL stai usando? Prodotti diversi avranno soluzioni diverse – APC

risposta

5

Ho provato alcuni dei altre soluzioni qui, tuttavia sembrano essere leggermente fuori, o l'ordine non era del tutto corretto.

Il mio tentativo di una soluzione di Microsoft SQL Server sembra funzionare correttamente:

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) 

Si noti che nel mio esempio, sto utilizzando solo TOP 2 piuttosto che TOP 10. Ciò è dovuto semplicemente al mio dati di test essere piuttosto più limitato. Puoi facilmente sostituire il 2 per un 10 nei tuoi dati.

Ecco lo script SQL per creare la tabella:

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 

E il mio dati assomiglia a questo:

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 

Si noti che il risultato della query sia correttamente ordinata dal complessivo valore delle vendite e non il codice paese alfabetico e che la categoria "Altro" è sempre l'ultima, anche se il valore aggregato delle vendite lo spingerebbe normalmente in cima all'elenco.

Non sto dicendo che questa sia la soluzione migliore (leggi: la più ottimale), tuttavia, per il set di dati che ho fornito sembra funzionare piuttosto bene.

0

dell'Unione nella top ten con un esterno Unisciti alla top ten con il tavolo per aggregare il resto.

io non ho accesso a SQL qui, ma io Hazzard una supposizione:

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 

Naturalmente, se questo è un top in rapida evoluzione (10), allora si può essere bloccato o mantenere una copia del top (10) per la durata della query.

0

In pseudo SQL: selezionare top 10 ordina per vendite UNION selezionare 'Altro', SUM (vendite) dove Ctry not in (select superiore 10 come sopra)

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

Ricordare che in base all'utilizzo (e al volume/restrizioni del database) è possibile ottenere gli stessi risultati utilizzando il codice dell'applicazione (python, nodo, C#, java ecc.). Sure it will depend on your use-case ma hey, è possibile.

ho finito per fare questo in C# per esempio:

// 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() 
     }); 

responsabilità

Capisco che questa è la domanda con tag "un solo SQL", ma ci potrebbero essere altre persone come me out c'è chi può fare uso del livello dell'applicazione invece di affidarsi solo a SQL per farlo accadere. Sto solo cercando di mostrare alle persone altri modi di fare la stessa cosa, che potrebbero essere utili. Anche se questo viene ridimensionato all'oblio, so che qualcuno sarà felice di leggerlo perché gli è stato insegnato a utilizzare ogni strumento per il meglio, e pensa "fuori dagli schemi".