Baru-baru ini, saya diberi tugas untuk mencetak semua bilangan prima (1-100). Saya gagal secara drastis di sana. Kode Saya:
Create Procedure PrintPrimeNumbers
@startnum int,
@endnum int
AS
BEGIN
Declare @a INT;
Declare @i INT = 1
(
Select a = @startnum / 2;
WHILE @i<@a
BEGIN
@startnum%(@a-@i)
i=i+1;
)
END
Meskipun saya berakhir tanpa menyelesaikannya, saya bertanya-tanya apakah itu layak untuk melakukan program-program seperti pada Database (SQL Server 2008 R2).
Jika ya, bagaimana itu bisa berakhir.
sql-server
sql-server-2008-r2
t-sql
ispostback
sumber
sumber
Jawaban:
Sejauh ini cara tercepat dan termudah untuk mencetak "semua bilangan prima (1-100)" adalah dengan sepenuhnya merangkul kenyataan bahwa bilangan prima adalah seperangkat nilai yang diketahui, terbatas, dan tidak berubah ("diketahui" dan "terbatas" dalam suatu kisaran tertentu, tentu saja). Pada skala sekecil ini, mengapa membuang-buang CPU setiap waktu untuk menghitung banyak nilai yang telah dikenal untuk waktu yang sangat lama, dan hampir tidak memerlukan memori untuk disimpan?
Tentu saja, jika Anda perlu menghitung bilangan prima antara 1 dan 100, berikut ini cukup efisien:
Kueri ini hanya menguji angka ganjil karena angka genap tidak akan menjadi yang utama. Ini juga spesifik untuk kisaran 1 - 100.
Sekarang, jika Anda memerlukan rentang dinamis (mirip dengan yang ditunjukkan pada contoh kode dalam pertanyaan), maka berikut ini adalah adaptasi dari kueri di atas yang masih agak efisien (dihitung rentang 1 - 100.000 - 9592 entri - hanya di bawah 1 detik):
Pengujian saya (menggunakan
SET STATISTICS TIME, IO ON;
) menunjukkan bahwa kueri ini berkinerja lebih baik daripada dua jawaban lain yang diberikan (sejauh ini):RANGE: 1 - 100
RANGE: 1 - 10.000
RANGE: 1 - 100.000
RANGE: 99.900 - 100.000
CATATAN : Untuk menjalankan tes ini, saya harus memperbaiki bug dalam kode Dan -
@startnum
tidak dimasukkan ke dalam kueri sehingga selalu dimulai pada1
. Saya menggantiDividend.num <= @endnum
saluran denganDividend.num BETWEEN @startnum AND @endnum
.RANGE: 1 - 100.000 (uji ulang parsial)
Setelah memperbaiki kueri Dan untuk pengujian 99.900 - 100.000, saya perhatikan bahwa tidak ada lagi bacaan logis yang terdaftar. Jadi saya menguji ulang kisaran ini dengan perbaikan yang masih diterapkan dan menemukan bahwa pembacaan logis hilang lagi dan waktunya sedikit lebih baik (dan ya, jumlah baris yang sama dikembalikan).
sumber
ROW_NUMBER() OVER (ORDER BY (SELECT 1))
? TidakROW_NUMBER() OVER ()
akan setara?OVER ()
, Anda akan mendapatkan error berikut:The function 'ROW_NUMBER' must have an OVER clause with ORDER BY.
. Dan, denganORDER BY
, itu tidak bisa menjadi konstanta, maka subquery mengembalikan konstanta.DECLARE @RangeStart INT = 999900, @RangeEnd INT = 1000000;
berfungsi tetapi begitu saya mengaturnyaDECLARE @RangeStart INT = 9999999900, @RangeEnd INT = 10000000000;
mengatakanMsg 8115, Level 16, State 2, Line 1 Arithmetic overflow error converting expression to data type int. Msg 1014, Level 15, State 1, Line 5 A TOP or FETCH clause contains an invalid value.
?INT
. Nilai maksimal yangINT
dapat disimpan adalah 2.147.483.647, yang lebih kecil dari nilai awal Anda sebesar 9.999.999.900. Anda mendapatkan kesalahan itu bahkan jika Anda hanya menjalankanDECLARE
. Anda dapat mencoba mengubah tipe data variabel menjadiBIGINT
dan melihat bagaimana hasilnya. Ada kemungkinan bahwa perubahan kecil lainnya akan diperlukan untuk mendukung itu. Untuk rentang tipe data, silakan lihat: int, bigint, smallint, dan tinyint .Cara sederhana namun tidak terlalu efisien untuk mengembalikan bilangan prima di kisaran 2-100 (1 tidak prima) adalah
Anda juga bisa berpotensi mewujudkan angka 2-100 dalam tabel dan menerapkan Saringan Eratosthenes melalui pembaruan atau penghapusan berulang.
sumber
Ya, itu layak tetapi saya tidak berpikir T-SQL adalah alat yang tepat untuk pekerjaan itu. Di bawah ini adalah contoh dari pendekatan berbasis set di T-SQL untuk masalah ini.
sumber
Kita dapat menulis kode di bawah ini dan berfungsi:
Di atas saya telah membuat Prosedur Tersimpan untuk mendapatkan bilangan prima.
Untuk mengetahui hasilnya, jalankan prosedur yang tersimpan:
sumber
sumber