Kijk eens naar SQL Server - Set-gebaseerde willekeurige getallen met een zeer gedetailleerde uitleg.
Samenvattend genereert de volgende code een willekeurig getal tussen 0 en 13 met een uniforme verdeling:
ABS(CHECKSUM(NewId())) % 14
Om uw bereik te wijzigen, hoeft u alleen het nummer aan het einde van de uitdrukking te wijzigen. Wees extra voorzichtig als u een bereik nodig heeft dat zowel positieve als negatieve getallen bevat. Als je het verkeerd doet, is het mogelijk om het getal 0 dubbel te tellen.
Een kleine waarschuwing voor de wiskundigen in de kamer:er zit een zeer lichte vertekening in deze code. CHECKSUM()
resulteert in getallen die uniform zijn over het hele bereik van het sql Int-gegevenstype, of op zijn minst zo dichtbij als mijn (de editor) testen kunnen aantonen. Er zal echter enige vertekening optreden wanneer CHECKSUM() een getal aan de bovenkant van dat bereik produceert. Elke keer dat u een getal krijgt tussen het maximaal mogelijke gehele getal en het laatste exacte veelvoud van de grootte van uw gewenste bereik (14 in dit geval) vóór dat maximale gehele getal, krijgen die resultaten de voorkeur boven het resterende deel van uw bereik dat niet kan worden geproduceerd uit dat laatste veelvoud van 14.
Stel je bijvoorbeeld voor dat het hele bereik van het Int-type slechts 19 is. 19 is het grootst mogelijke gehele getal dat je kunt vasthouden. Wanneer CHECKSUM() resulteert in 14-19, komen deze overeen met resultaten 0-5. Die cijfers zouden zwaar . zijn voorkeur boven 6-13, omdat CHECKSUM() twee keer zoveel kans heeft om ze te genereren. Het is gemakkelijker om dit visueel aan te tonen. Hieronder vindt u de volledige mogelijke reeks resultaten voor ons denkbeeldige gehele bereik:
Checksum Integer: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Range Result: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 0 1 2 3 4 5
Je kunt hier zien dat er meer kansen zijn om sommige getallen te produceren dan andere:bias. Gelukkig is het werkelijke bereik van het type Int veel groter... zo erg zelfs dat in de meeste gevallen de vertekening bijna niet waarneembaar is. Het is echter iets om op te letten als u dit ooit doet voor een serieuze beveiligingscode.