611 Stimmen

Wie kann man eine zufällige Zeile in SQL anfordern?

Wie kann ich in reinem SQL eine zufällige Zeile anfordern (oder eine, die dem echten Zufall so nahe wie möglich kommt)?

876voto

Yaakov Ellis Punkte 39402

Siehe diesen Beitrag: SQL zur Auswahl einer zufälligen Zeile aus einer Datenbanktabelle . Es werden Methoden beschrieben, um dies in MySQL, PostgreSQL, Microsoft SQL Server, IBM DB2 und Oracle zu tun (das Folgende ist von diesem Link kopiert):

Wählen Sie mit MySQL eine beliebige Zeile aus:

SELECT column FROM table
ORDER BY RAND()
LIMIT 1

Wählen Sie eine zufällige Zeile mit PostgreSQL aus:

SELECT column FROM table
ORDER BY RANDOM()
LIMIT 1

Wählen Sie mit Microsoft SQL Server eine beliebige Zeile aus:

SELECT TOP 1 column FROM table
ORDER BY NEWID()

Auswahl einer zufälligen Zeile mit IBM DB2

SELECT column, RAND() as IDX 
FROM table 
ORDER BY IDX FETCH FIRST 1 ROWS ONLY

Wählen Sie mit Oracle einen zufälligen Datensatz aus:

SELECT column FROM
( SELECT column FROM table
ORDER BY dbms_random.value )
WHERE rownum = 1

185voto

Grey Panther Punkte 12478

Lösungen wie Jeremies:

SELECT * FROM table ORDER BY RAND() LIMIT 1

funktionieren, aber sie benötigen einen sequentiellen Scan der gesamten Tabelle (weil der Zufallswert für jede Zeile berechnet werden muss, damit die kleinste Zeile ermittelt werden kann), was selbst bei mittelgroßen Tabellen recht langsam sein kann. Meine Empfehlung wäre, eine Art indizierte numerische Spalte zu verwenden (viele Tabellen haben diese als Primärschlüssel), und dann etwas zu schreiben wie:

SELECT * FROM table WHERE num_value >= RAND() * 
    ( SELECT MAX (num_value ) FROM table ) 
ORDER BY num_value LIMIT 1

Dies funktioniert in logarithmischer Zeit, unabhängig von der Tabellengröße, wenn num_value indiziert ist. Ein Vorbehalt: Dies setzt voraus, dass num_value ist gleichmäßig verteilt in dem Bereich 0..MAX(num_value) . Wenn Ihr Datensatz stark von dieser Annahme abweicht, erhalten Sie verzerrte Ergebnisse (einige Zeilen werden häufiger als andere erscheinen).

72voto

Matt Hamilton Punkte 193704

Ich weiß nicht, wie effizient das ist, aber ich habe es schon einmal benutzt:

SELECT TOP 1 * FROM MyTable ORDER BY newid()

Da GUIDs ziemlich zufällig sind, bedeutet die Reihenfolge, dass Sie eine zufällige Zeile erhalten.

40voto

Neel Punkte 369
ORDER BY NEWID()

nimmt 7.4 milliseconds

WHERE num_value >= RAND() * (SELECT MAX(num_value) FROM table)

nimmt 0.0065 milliseconds ¡!

Ich werde auf jeden Fall die letztere Methode anwenden.

17voto

Jon Galloway Punkte 51200

Sie haben nicht gesagt, welchen Server Sie verwenden. In älteren Versionen von SQL Server können Sie dies verwenden:

select top 1 * from mytable order by newid()

In SQL Server 2005 und höher können Sie TABLESAMPLE um eine Zufallsstichprobe zu erhalten, die wiederholbar ist:

SELECT FirstName, LastName
FROM Contact 
TABLESAMPLE (1 ROWS) ;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X