Seperti judulnya saya butuh bantuan untuk mendapatkan total berjalan dalam T-SQL. Masalahnya adalah jumlah yang harus saya lakukan adalah jumlah hitungan:
sum(count (distinct (customers)))
Katakanlah jika saya menghitung sendiri, hasilnya adalah:
Day | CountCustomers
----------------------
5/1 | 1
5/2 | 0
5/3 | 5
Saya perlu output dengan jumlah menjadi:
Day | RunningTotalCustomers
----------------------
5/1 | 1
5/2 | 1
5/3 | 6
Saya sudah selesai menjalankan total sebelum menggunakan coalesce
metode ini, tetapi tidak pernah dengan hitungan. Saya tidak yakin bagaimana melakukannya sekarang karena saya memiliki hitungan.
sql-server
t-sql
Aaron Bertrand
sumber
sumber
Day
kuncinya, dan apakah nilainya berdekatan?Jawaban:
Berikut adalah beberapa metode yang dapat Anda bandingkan. Pertama mari kita buat tabel dengan beberapa data dummy. Saya mengisi ini dengan banyak data acak dari sys.all_columns. Yah, ini agak acak - saya memastikan bahwa tanggalnya berdekatan (yang benar-benar hanya penting untuk salah satu jawaban).
Hasil:
Data terlihat seperti ini (5000 baris) - tetapi akan terlihat sedikit berbeda pada sistem Anda tergantung pada versi dan versi #:
Dan hasil total yang berjalan akan terlihat seperti ini (501 baris):
Jadi metode yang akan saya bandingkan adalah:
bergabung sendiri
Ini adalah cara orang akan mengatakan kepada Anda untuk melakukannya ketika mereka memperingatkan Anda untuk menjauh dari kursor, karena "berbasis set selalu lebih cepat." Dalam beberapa percobaan baru-baru ini saya telah menemukan bahwa kursor melampaui solusi ini.
CTE rekursif dengan tanggal
Pengingat - ini bergantung pada tanggal yang berdekatan (tanpa celah), hingga 10.000 tingkat rekursi, dan Anda tahu tanggal mulai rentang yang Anda minati (untuk mengatur jangkar). Anda dapat mengatur jangkar secara dinamis menggunakan subquery, tentu saja, tetapi saya ingin menyederhanakannya.
cte rekursif dengan row_number
Perhitungan Row_number sedikit mahal di sini. Sekali lagi ini mendukung level maksimum rekursi 10000, tetapi Anda tidak perlu menetapkan jangkar.
cte rekursif dengan tabel temp
Mencuri dari jawaban Mikael, seperti yang disarankan, untuk memasukkan ini dalam tes.
pembaruan yang unik
Sekali lagi saya hanya memasukkan ini untuk kelengkapan; Saya pribadi tidak akan bergantung pada solusi ini karena, seperti yang saya sebutkan pada jawaban lain, metode ini tidak dijamin berfungsi sama sekali, dan mungkin benar-benar merusak versi SQL Server yang akan datang. (Saya melakukan yang terbaik untuk memaksa SQL Server mematuhi perintah yang saya inginkan, menggunakan petunjuk untuk pilihan indeks.)
kursor
"Waspadalah, ada kursor di sini! Kursor itu jahat! Kamu harus menghindari kursor di semua biaya!" Tidak, itu bukan saya yang berbicara, itu hanya hal yang saya dengar banyak. Berlawanan dengan pendapat umum, ada beberapa kasus di mana kursor sesuai.
SQL Server 2012
Jika Anda menggunakan SQL Server versi terbaru, peningkatan fungsionalitas windowing memungkinkan kami untuk menghitung total running dengan mudah tanpa biaya eksponensial dari self-gabung (SUM dihitung dalam satu pass), kompleksitas CTE (termasuk persyaratan) baris yang berdekatan untuk CTE yang berkinerja lebih baik), pembaruan unik yang tidak didukung, dan kursor terlarang. Berhati-hatilah dengan perbedaan antara menggunakan
RANGE
danROWS
, atau tidak menentukan sama sekali - hanyaROWS
menghindari spool pada disk, yang akan menghambat kinerja secara signifikan.perbandingan kinerja
Saya mengambil setiap pendekatan dan membungkusnya menggunakan berikut ini:
Berikut adalah hasil dari total durasi, dalam milidetik (ingat ini termasuk perintah DBCC setiap kali juga):
Dan saya melakukannya lagi tanpa perintah DBCC:
Menghapus DBCC dan loop, hanya mengukur satu iterasi mentah:
Akhirnya, saya mengalikan jumlah baris dalam tabel sumber dengan 10 (mengubah atas menjadi 50.000 dan menambahkan tabel lain sebagai gabungan silang). Hasil ini, satu iterasi tunggal tanpa perintah DBCC (hanya untuk kepentingan waktu):
Saya hanya mengukur durasi - Saya akan menyerahkannya kepada pembaca untuk membandingkan pendekatan ini pada data mereka, membandingkan metrik lain yang mungkin penting (atau mungkin berbeda dengan skema / data mereka). Sebelum menarik kesimpulan apa pun dari jawaban ini, terserah Anda untuk mengujinya terhadap data dan skema Anda ... hasil ini hampir pasti akan berubah karena jumlah baris semakin tinggi.
demo
Saya telah menambahkan sqlfiddle . Hasil:
kesimpulan
Dalam tes saya, pilihannya adalah:
Tetapi sekali lagi, Anda harus menguji ini terhadap skema dan data Anda. Karena ini adalah tes yang dibuat dengan jumlah baris yang relatif rendah, itu mungkin juga kentut dalam angin. Saya telah melakukan tes lain dengan skema dan jumlah baris yang berbeda, dan heuristik kinerja sangat berbeda ... itulah sebabnya saya mengajukan begitu banyak pertanyaan lanjutan ke pertanyaan awal Anda.
MEMPERBARUI
Saya telah membuat blog lebih banyak tentang ini di sini:
Pendekatan terbaik untuk menjalankan total - diperbarui untuk SQL Server 2012
sumber
Ini, tampaknya, adalah solusi optimal
sumber
day
Misalnya .Hanya cara lain, mahal, tetapi versi independen. Itu tidak menggunakan tabel temp atau variabel.
sumber