Ho una tabella che include una colonna di valori decimali, come questa:
id value size
-- ----- ----
1 100 .02
2 99 .38
3 98 .13
4 97 .35
5 96 .15
6 95 .57
7 94 .25
8 93 .15
Quello che devo realizzare è un po 'difficile da descrivere, quindi per favore abbi pazienza. Quello che sto cercando di fare è creare un valore aggregato della size
colonna che aumenta di 1 ogni volta che le righe precedenti si sommano a 1, in ordine decrescente secondo value
. Il risultato sarebbe simile al seguente:
id value size bucket
-- ----- ---- ------
1 100 .02 1
2 99 .38 1
3 98 .13 1
4 97 .35 1
5 96 .15 2
6 95 .57 2
7 94 .25 2
8 93 .15 3
Il mio ingenuo primo tentativo è stato quello di mantenere una corsa SUM
e poi CEILING
quel valore, tuttavia non gestisce il caso in cui alcuni record size
finiscono per contribuire al totale di due secchi separati. L'esempio seguente potrebbe chiarire questo:
id value size crude_sum crude_bucket distinct_sum bucket
-- ----- ---- --------- ------------ ------------ ------
1 100 .02 .02 1 .02 1
2 99 .38 .40 1 .40 1
3 98 .13 .53 1 .53 1
4 97 .35 .88 1 .88 1
5 96 .15 1.03 2 .15 2
6 95 .57 1.60 2 .72 2
7 94 .25 1.85 2 .97 2
8 93 .15 2.00 2 .15 3
Come puoi vedere, se dovessi semplicemente utilizzare CEILING
il crude_sum
record n. 8, verrebbe assegnato al bucket 2. Ciò è causato dalla size
divisione dei record n. 5 e n. 8 su due bucket. Invece, la soluzione ideale è reimpostare la somma ogni volta che raggiunge 1, che quindi incrementa la bucket
colonna e inizia una nuova SUM
operazione a partire dal size
valore del record corrente. Poiché l'ordine dei record è importante per questa operazione, ho incluso la value
colonna, che deve essere ordinata in ordine decrescente.
I miei tentativi iniziali hanno comportato l'esecuzione di più passaggi sui dati, una volta per eseguire l' SUM
operazione, ancora una volta a CEILING
quello, ecc. Ecco un esempio di ciò che ho fatto per creare la crude_sum
colonna:
SELECT
id,
value,
size,
(SELECT TOP 1 SUM(size) FROM table t2 WHERE t2.value<=t1.value) as crude_sum
FROM
table t1
Che è stato usato in UPDATE
un'operazione per inserire il valore in una tabella con cui lavorare in seguito.
Modifica: mi piacerebbe fare un altro tentativo di spiegarlo, quindi ecco qui. Immagina che ogni record sia un oggetto fisico. A quell'elemento è associato un valore e una dimensione fisica inferiore a uno. Ho una serie di secchi con una capacità di volume esattamente di 1 e ho bisogno di determinare quanti di questi secchi avrò bisogno e quale secchio entra ogni articolo in base al valore dell'articolo, ordinati dal più alto al più basso.
Un oggetto fisico non può esistere in due posti contemporaneamente, quindi deve trovarsi in un secchio o nell'altro. Questo è il motivo per cui non riesco a fare una CEILING
soluzione total + in esecuzione , perché ciò consentirebbe ai record di contribuire con le loro dimensioni a due bucket.
distinct_count
complica le cose. Aaron Bertrand ha un ottimo riepilogo delle opzioni su SQL Server per questo tipo di lavori con finestre. Ho usato il metodo "aggiornamento stravagante" per calcolare distinct_sum
, che puoi vedere qui su SQL Fiddle , ma questo non è affidabile.