Saya memiliki tabel yang menyertakan kolom nilai desimal, seperti ini:
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
Apa yang perlu saya capai sedikit sulit untuk dijelaskan, jadi tolong tahan dengan saya. Apa yang saya coba lakukan adalah membuat nilai agregat sizekolom yang bertambah 1 setiap kali baris sebelumnya berjumlah 1, ketika dalam urutan menurun menurut value. Hasilnya akan terlihat seperti ini:
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
Upaya naif pertama saya adalah tetap berjalan SUMdan kemudian CEILINGnilai itu, namun itu tidak menangani kasus di mana beberapa catatan sizeakhirnya berkontribusi terhadap total dua ember terpisah. Contoh di bawah ini dapat menjelaskan hal ini:
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
Seperti yang Anda lihat, jika saya hanya menggunakan CEILINGpada crude_sumrecord # 8 akan ditugaskan ke bucket 2. Ini disebabkan oleh sizerecord # 5 dan # 8 yang dibagi menjadi dua ember. Sebagai gantinya, solusi ideal adalah mengatur ulang jumlah setiap kali mencapai 1, yang kemudian menambah bucketkolom dan memulai SUMoperasi baru mulai dari sizenilai catatan saat ini. Karena urutan catatan penting untuk operasi ini, saya telah memasukkan valuekolom, yang dimaksudkan untuk diurutkan dalam urutan menurun.
Upaya awal saya telah melibatkan membuat beberapa melewati data, sekali untuk melakukan SUMoperasi, sekali lagi untuk CEILINGitu, dll. Berikut adalah contoh dari apa yang saya lakukan untuk membuat crude_sumkolom:
SELECT
id,
value,
size,
(SELECT TOP 1 SUM(size) FROM table t2 WHERE t2.value<=t1.value) as crude_sum
FROM
table t1
Yang digunakan dalam UPDATEoperasi untuk memasukkan nilai ke dalam tabel untuk dikerjakan nanti.
Sunting: Saya ingin mengambil langkah lain dalam menjelaskan ini, jadi begini. Bayangkan setiap catatan adalah benda fisik. Item itu memiliki nilai yang terkait dengannya, dan ukuran fisiknya kurang dari satu. Saya memiliki serangkaian ember dengan kapasitas volume tepat 1, dan saya perlu menentukan berapa banyak ember yang akan saya butuhkan dan ember mana yang dimasukkan setiap item sesuai dengan nilai item, diurutkan dari tertinggi ke terendah.
Item fisik tidak dapat ada di dua tempat sekaligus, jadi item tersebut harus berada dalam satu ember atau lainnya. Inilah sebabnya saya tidak dapat menjalankan CEILINGsolusi total + berjalan , karena itu akan memungkinkan catatan berkontribusi ukurannya menjadi dua ember.
distinct_counthal-hal yang rumit. Aaron Bertrand memiliki ringkasan opsi Anda di SQL Server untuk jenis pekerjaan windowing ini. Saya telah menggunakan metode "pembaruan unik" untuk menghitung distinct_sum, yang dapat Anda lihat di sini di SQL Fiddle , tetapi ini tidak dapat diandalkan.