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 size
kolom 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 SUM
dan kemudian CEILING
nilai itu, namun itu tidak menangani kasus di mana beberapa catatan size
akhirnya 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 CEILING
pada crude_sum
record # 8 akan ditugaskan ke bucket 2. Ini disebabkan oleh size
record # 5 dan # 8 yang dibagi menjadi dua ember. Sebagai gantinya, solusi ideal adalah mengatur ulang jumlah setiap kali mencapai 1, yang kemudian menambah bucket
kolom dan memulai SUM
operasi baru mulai dari size
nilai catatan saat ini. Karena urutan catatan penting untuk operasi ini, saya telah memasukkan value
kolom, yang dimaksudkan untuk diurutkan dalam urutan menurun.
Upaya awal saya telah melibatkan membuat beberapa melewati data, sekali untuk melakukan SUM
operasi, sekali lagi untuk CEILING
itu, dll. Berikut adalah contoh dari apa yang saya lakukan untuk membuat crude_sum
kolom:
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 UPDATE
operasi 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 CEILING
solusi total + berjalan , karena itu akan memungkinkan catatan berkontribusi ukurannya menjadi dua ember.
distinct_count
hal-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.