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 sizecolonna 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 SUMe poi CEILINGquel valore, tuttavia non gestisce il caso in cui alcuni record sizefiniscono 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 CEILINGil crude_sumrecord n. 8, verrebbe assegnato al bucket 2. Ciò è causato dalla sizedivisione 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 bucketcolonna e inizia una nuova SUMoperazione a partire dal sizevalore del record corrente. Poiché l'ordine dei record è importante per questa operazione, ho incluso la valuecolonna, 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' SUMoperazione, ancora una volta a CEILINGquello, ecc. Ecco un esempio di ciò che ho fatto per creare la crude_sumcolonna:
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 UPDATEun'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 CEILINGsoluzione total + in esecuzione , perché ciò consentirebbe ai record di contribuire con le loro dimensioni a due bucket.
distinct_countcomplica 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.