2015-10-30 18 views
6

Ho una vista che elenca data, customerID, orderID e orderCost. Come seleziono il cliente massimo di spesa al mese? I dati si estende solo un periodo di sei mesi nel 2015.Come selezionare il numero massimo di clienti al mese

sono in grado di ottenere la somma speso da ciascun cliente ogni mese, ma non il massimo spesa dei clienti con:

SELECT EXTRACT(YEAR FROM date) AS year, MONTHNAME(date) AS month, customerID, SUM(orderCost) 
FROM CustomerPricedOrder 
GROUP BY MONTH(date), customerID; 

* dove è CustomerPricedOrder una vista che prende i dati da una tabella dal titolo CustomerOrder

Come posso trovare il cliente massimo di spesa al mese con una procedura memorizzata? Ho bisogno di un cursore?

Un esempio di output ho bisogno quando chiamo la procedura:

  • l'anno ........ mese ......... customerID
  • 2015 ... ..... Gennaio ....... 4
  • 2015 ........ Febbraio ...... 21
  • 2015 ........ Marzo ... ...... 6
  • 2015 ........ Aprile ......... 11

dove customerID è il cliente di spesa più alto di quel mese.

+1

Questo è un problema ben noto, vedere il tag http://stackoverflow.com/questions/tagged/greatest-n-per-group –

risposta

0

Alex,

Potete per favore provare questo

SELECT EXTRACT(YEAR FROM date) AS year, MONTHNAME(date) AS month, customerID, SUM(orderCost) AS cost 
FROM CustomerPricedOrder 
GROUP BY MONTH(date), customerID ORDER BY cost DESC; 

Se il mio cervello capito correttamente questo dovrebbe fare il lavoro.

3

Potete semplicemente ordinare per somma decrescente e limite 1?

SELECT EXTRACT(YEAR FROM date) AS year, MONTHNAME(date) AS month, customerID, SUM(orderCost) as sum_of_order_cost FROM CustomerPricedOrder GROUP BY MONTH(date), customerID order by sum_of_order_cost desc limit 1; 
+0

'ordine da sum_of_order_cost' darebbe un errore di identificazione valido. – brenners1302

0

Ecco un modo utilizzando le variabili per simulare row_number(). La query ranghi ogni cliente all'interno di un gruppo (in cui ogni gruppo rappresenta un mese) a partire dal 1 per il più alto cliente di spesa, e mantiene quelli con il numero 1:

SELECT * FROM (
    SELECT @rn := if(@prevMonth = month AND @prevYear = year, @rn + 1, 1) rn, 
      @prevMonth := month, @prevYear := year, * 
    FROM ( 
     SELECT YEAR(date) AS year, 
      MONTHNAME(date) AS month, 
      customerID, 
      SUM(orderCost) AS sum_order_cost 
     FROM CustomerPricedOrder 
     GROUP BY MONTHNAME(date), YEAR(date), customerID 
    ) t ORDER BY year, month, sum_order_cost desc 
) t WHERE rn = 1 
0

provare questo ....

SELECT EXTRACT(YEAR FROM date) AS year, 
MONTHNAME(date) AS month, 
customerID, 
SUM(orderCost) as sum_of_order_cost, 
MAX(sum_of_order_cost) FROM CustomerPricedOrder 
GROUP BY MONTH(date), customerID 
order by orderCost; 
+1

@Alexander, quest'anno dovrebbe funzionare, provatelo –

1
SELECT EXTRACT(YEAR FROM date) AS year, 
MONTHNAME(date) AS month, 
customerID, 
SUM(orderCost) as sum_order_cost, 
MAX(sum_of_order_cost) FROM CustomerPricedOrder 
GROUP BY MONTH(date), customerID 
order by sum_order_cost DESC 
LIMIT 1 

Questo potrebbe funzionare

0

Sembra come un'applicazione dritto in avanti delle funzioni analitiche

select year, month, customer, amount, 
    rank() OVER (PARTITION BY year, month ORDER BY amount DESC) rn 
    (
      SELECT EXTRACT(YEAR FROM date) AS year, MONTHNAME(date) AS month,customerID, SUM(orderCost) amount 
      FROM CustomerPricedOrder 
      GROUP BY MONTH(date), customerID 
    ) 

; 

Questo indicherà l'importo per anno/mese con l'importo più alto assegnato a rn -> 1. La domanda di carattere generale da tenere presente quando si utilizzano le funzioni analitiche è come si desidera gestire "risultati uguali" (ovvero due clienti con lo stesso importo in un periodo). Verificare se il caso deve essere gestito e se Row_Number è più adatto alle proprie esigenze (forza la numerazione univoca anche per risultati uguali, mentre rank() assegnerà lo stesso numero di ordine per risultati uguali), oppure è necessario aggiungere ai criteri di ordinamento nel funzione analitica.

Problemi correlati