Saya perlu nomor acak yang berbeda untuk setiap baris di meja saya. Kode yang tampaknya jelas berikut ini menggunakan nilai acak yang sama untuk setiap baris.
SELECT table_name, RAND() magic_number
FROM information_schema.tables
Saya ingin mendapatkan INT atau FLOAT dari ini. Kisah selanjutnya adalah saya akan menggunakan nomor acak ini untuk membuat offset tanggal acak dari tanggal yang diketahui, misalnya 1-14 hari dari tanggal mulai.
Ini untuk Microsoft SQL Server 2000.
sql-server
tsql
sql-server-2000
MatthewMartin
sumber
sumber
Jawaban:
Lihatlah SQL Server - Tetapkan nomor acak berbasis yang memiliki penjelasan yang sangat rinci.
Untuk meringkas, kode berikut menghasilkan angka acak antara 0 dan 13 termasuk dengan distribusi seragam:
Untuk mengubah rentang Anda, cukup ubah angka di akhir ekspresi. Berhati-hatilah jika Anda membutuhkan rentang yang mencakup angka positif dan negatif. Jika Anda salah melakukannya, Anda dapat menghitung dua kali angka 0.
Peringatan kecil untuk kacang matematika di ruangan: ada sedikit bias dalam kode ini.
CHECKSUM()
menghasilkan angka yang seragam di seluruh jajaran datatype sql Int, atau setidaknya sedekat yang dapat ditunjukkan oleh pengujian (editor) saya. Namun, akan ada beberapa bias ketika CHECKSUM () menghasilkan angka di bagian paling atas dari rentang itu. Setiap kali Anda mendapatkan angka antara bilangan bulat maksimum yang mungkin dan kelipatan tepat terakhir dari ukuran rentang yang Anda inginkan (14 dalam kasus ini) sebelum bilangan bulat maksimum itu, hasil-hasil itu disukai daripada bagian sisa rentang Anda yang tidak dapat dihasilkan dari kelipatan terakhir dari 14.Sebagai contoh, bayangkan seluruh rentang tipe Int hanya 19. 19 adalah bilangan bulat terbesar yang bisa Anda pegang. Ketika CHECKSUM () menghasilkan 14-19, ini sesuai dengan hasil 0-5. Angka-angka itu akan sangat disukai di atas 6-13, karena CHECKSUM () dua kali lebih mungkin menghasilkannya. Lebih mudah untuk menunjukkan ini secara visual. Di bawah ini adalah seluruh rangkaian hasil yang mungkin untuk rentang integer imajiner kami:
Anda dapat melihat di sini bahwa ada lebih banyak peluang untuk menghasilkan beberapa angka daripada yang lain: bias. Untungnya, kisaran sebenarnya dari tipe Int jauh lebih besar ... begitu banyak sehingga dalam kebanyakan kasus biasnya hampir tidak terdeteksi. Namun, ini adalah sesuatu yang harus diperhatikan jika Anda menemukan diri Anda melakukan ini untuk kode keamanan serius.
sumber
Ketika dipanggil beberapa kali dalam satu batch, rand () mengembalikan nomor yang sama.
Saya sarankan menggunakan convert (
varbinary
,newid()
) sebagai argumen seed:newid()
dijamin untuk mengembalikan nilai yang berbeda setiap kali dipanggil, bahkan dalam batch yang sama, jadi menggunakannya sebagai seed akan meminta rand () untuk memberikan nilai yang berbeda setiap kali.Diedit untuk mendapatkan bilangan bulat acak dari 1 hingga 14.
sumber
Di atas akan menghasilkan angka acak (pseudo-) antara 0 dan 1, eksklusif. Jika digunakan dalam pilih, karena nilai seed berubah untuk setiap baris, itu akan menghasilkan angka acak baru untuk setiap baris (namun tidak dijamin untuk menghasilkan nomor unik per baris).
Contoh ketika dikombinasikan dengan batas atas 10 (menghasilkan angka 1 - 10):
Dokumentasi Transact-SQL:
CAST()
: https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sqlRAND()
: http://msdn.microsoft.com/en-us/library/ms177610.aspxCHECKSUM()
: http://msdn.microsoft.com/en-us/library/ms189788.aspxNEWID()
: https://docs.microsoft.com/en-us/sql/t-sql/functions/newid-transact-sqlsumber
Pembuatan angka acak antara 1000 dan 9999 inklusif:
"+1" - untuk memasukkan nilai batas atas (9999 untuk contoh sebelumnya)
sumber
FLOOR(RAND(CHECKSUM(NEWID()))*(10000-1000)+1000)
Menjawab pertanyaan lama, tetapi jawaban ini belum pernah diberikan sebelumnya, dan semoga ini akan bermanfaat bagi seseorang yang menemukan hasil ini melalui mesin pencari.
Dengan SQL Server 2008, fungsi baru telah diperkenalkan
CRYPT_GEN_RANDOM(8)
,, yang menggunakan CryptoAPI untuk menghasilkan angka acak kriptografis yang kuat, dikembalikan sebagaiVARBINARY(8000)
. Inilah halaman dokumentasi: https://docs.microsoft.com/en-us/sql/t-sql/functions/crypt-gen-random-transact-sqlJadi untuk mendapatkan nomor acak, Anda cukup memanggil fungsi dan melemparkannya ke jenis yang diperlukan:
atau untuk mendapatkan
float
antara -1 dan +1, Anda dapat melakukan sesuatu seperti ini:sumber
Fungsi Rand () akan menghasilkan nomor acak yang sama, jika digunakan dalam tabel SELECT query. Hal yang sama berlaku jika Anda menggunakan seed ke fungsi Rand. Cara alternatif untuk melakukannya, adalah menggunakan ini:
Dapatkan informasi dari sini , yang menjelaskan masalahnya dengan sangat baik.
sumber
Apakah Anda memiliki nilai integer di setiap baris yang bisa Anda berikan sebagai seed ke fungsi RAND?
Untuk mendapatkan bilangan bulat antara 1 dan 14, saya yakin ini akan berhasil:
sumber
RAND(<seed>)
tampaknya tidak terlalu acak untuk perubahan kecil di<seed>
. Sebagai contoh tes cepat yang saya lakukan: Saya membiarkan<seed>
184380, 184383, 184386, dan nilai yang sesuaiRAND(<seed>)
adalah: 0,14912, 0,14917, 0,14923.RAND(<seed>)*100000) - FLOOR(RAND(<seed>)*100000)
Jika Anda perlu menyimpan benih Anda sehingga menghasilkan data acak "sama" setiap kali, Anda dapat melakukan hal berikut:
1. Buat tampilan yang mengembalikan pilih rand ()
2. Buat UDF yang memilih nilai dari tampilan.
3. Sebelum memilih data Anda, seed fungsi rand (), dan kemudian gunakan UDF dalam pernyataan pilih Anda.
sumber
coba gunakan nilai seed di RAND (seedInt). RAND () hanya akan mengeksekusi sekali per pernyataan itu sebabnya Anda melihat nomor yang sama setiap kali.
sumber
RIGHT(CONVERT(BIGINT, RAND(RecNo) * 1000000000000), 2)
(catatan: Saya melihatRIGHT
secara implisit mengonversikanBIGINT
keCHAR
, tetapi untuk lebih teliti, Anda akan memiliki yang lainCONVERT
di sana).Jika Anda tidak perlu menjadi bilangan bulat, tetapi pengidentifikasi unik acak apa pun, Anda dapat menggunakannya
newid()
sumber
Anda perlu memanggil RAND () untuk setiap baris. Ini adalah contoh yang bagus
https://web.archive.org/web/20090216200320/http://dotnet.org.za/calmyourself/archive/2007/04/13/sql-rand-trap-same-value-per-row.aspx
sumber
RAND()
ke tampilan, menempatkanSELECT
pandangan itu ke dalam fungsi, dan kemudian memanggil fungsi dari mana saja. Pintar.Di sini angka acak akan berada di antara 20 dan 30.
round
akan memberikan dua tempat desimal maksimum.Jika Anda ingin angka negatif, Anda dapat melakukannya dengan
Maka nilai min akan menjadi -60 dan maks akan menjadi -50.
sumber
Semudah:
Dan ini akan menempatkan angka acak antara 0-99 ke dalam tabel:
sumber
Masalah yang kadang-kadang saya miliki dengan "Jawaban" yang dipilih adalah bahwa distribusi tidak selalu genap. Jika Anda memerlukan distribusi acak dari 1 - 14 acak di antara banyak baris, Anda dapat melakukan sesuatu seperti ini (database saya memiliki 511 tabel, jadi ini berfungsi. Jika Anda memiliki lebih sedikit baris daripada yang Anda lakukan rentang angka acak, ini tidak berfungsi baik):
Jenis ini melakukan kebalikan dari solusi acak normal dalam arti bahwa itu membuat angka diurutkan dan mengacak kolom lainnya.
Ingat, saya memiliki 511 tabel di basis data saya (yang bersangkutan hanya b / c yang kami pilih dari information_schema). Jika saya mengambil kueri sebelumnya dan memasukkannya ke tabel temp #X, lalu jalankan kueri ini pada data yang dihasilkan:
Saya mendapatkan hasil ini, menunjukkan kepada saya bahwa nomor acak saya SANGAT merata di antara banyak baris:
sumber
selalu bekerja untuk saya
sumber
Gunakan newid ()
atau mungkin ini
sumber
sumber
Coba ini:
Di mana
a
angka bawah danb
angka atassumber
Angka antara 1 dan 10.
sumber