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)?

1voto

klyd Punkte 3789

Ich habe diese Variation in den Antworten noch nicht ganz gesehen. Ich hatte eine zusätzliche Einschränkung, bei der ich bei einem anfänglichen Seed jedes Mal denselben Satz von Zeilen auswählen musste.

Für MS SQL:

Minimales Beispiel:

select top 10 percent *
from table_name
order by rand(checksum(*))

Normalisierte Ausführungszeit: 1.00

Beispiel NewId():

select top 10 percent *
from table_name
order by newid()

Normalisierte Ausführungszeit: 1,02

NewId() ist nur unwesentlich langsamer als rand(checksum(*)) Daher sollten Sie es nicht für große Datensätze verwenden.

Auswahl mit Initialseed:

declare @seed int
set @seed = Year(getdate()) * month(getdate()) /* any other initial seed here */

select top 10 percent *
from table_name
order by rand(checksum(*) % seed) /* any other math function here */

Wenn Sie die gleiche Menge bei einem Saatgut auswählen müssen, scheint dies zu funktionieren.

1voto

hegemon Punkte 6256

Die meisten der hier vorgestellten Lösungen zielen darauf ab, das Sortieren zu vermeiden, aber sie müssen immer noch einen sequentiellen Scan über eine Tabelle durchführen.

Es gibt auch eine Möglichkeit, die sequentielle Suche zu vermeiden, indem man zur Indexsuche übergeht. Wenn Sie den Indexwert Ihrer zufälligen Zeile kennen, können Sie das Ergebnis fast sofort erhalten. Das Problem ist, wie man einen Indexwert errät.

Die folgende Lösung funktioniert mit PostgreSQL 8.4:

explain analyze select * from cms_refs where rec_id in 
  (select (random()*(select last_value from cms_refs_rec_id_seq))::bigint 
   from generate_series(1,10))
  limit 1;

Bei der obigen Lösung erraten Sie 10 verschiedene zufällige Indexwerte aus dem Bereich 0 [letzter Wert der ID].

Die Zahl 10 ist willkürlich - Sie können auch 100 oder 1000 verwenden, da dies (erstaunlicherweise) keinen großen Einfluss auf die Antwortzeit hat.

Es gibt auch ein Problem - wenn Sie spärliche IDs haben die Sie vermissen könnten . Die Lösung besteht darin einen Notfallplan haben :) In diesem Fall eine reine alte order by random()-Abfrage. Wenn kombiniert id sieht wie folgt aus:

explain analyze select * from cms_refs where rec_id in 
    (select (random()*(select last_value from cms_refs_rec_id_seq))::bigint 
     from generate_series(1,10))
    union all (select * from cms_refs order by random() limit 1)
    limit 1;

Nicht die Gewerkschaft ALLE Klausel. In diesem Fall, wenn der erste Teil Daten zurückgibt, wird der zweite Teil NIE ausgeführt!

1voto

Paige Ruten Punkte 164391
 SELECT * FROM table ORDER BY RAND() LIMIT 1

0voto

sev3ryn Punkte 1025

Für Oracle gibt es eine bessere Lösung als die Verwendung von dbms_random.value, die jedoch einen vollständigen Scan erfordert, um Zeilen nach dbms_random.value zu ordnen, und bei großen Tabellen recht langsam ist.

Verwenden Sie stattdessen dies:

SELECT *
FROM employee sample(1)
WHERE rownum=1

0voto

Mmmh mmh Punkte 5128

Ein einfacher und effizienter Weg von http://akinas.com/pages/en/blog/mysql_random_row/

SET @i = (SELECT FLOOR(RAND() * COUNT(*)) FROM table); PREPARE get_stmt FROM 'SELECT * FROM table LIMIT ?, 1'; EXECUTE get_stmt USING @i;

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