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

0voto

DAVID Punkte 1

Es scheint, dass viele der aufgelisteten Ideen nach wie vor für die Bestellung

Wenn Sie jedoch eine temporäre Tabelle verwenden, können Sie einen Zufallsindex zuweisen (wie viele der Lösungen vorgeschlagen haben) und dann den ersten Index nehmen, der größer als eine beliebige Zahl zwischen 0 und 1 ist.

Zum Beispiel (für DB2):

WITH TEMP AS (
SELECT COMLUMN, RAND() AS IDX FROM TABLE)
SELECT COLUMN FROM TABLE WHERE IDX > .5
FETCH FIRST 1 ROW ONLY

0voto

Sean Turner Punkte 1168

Seien Sie vorsichtig, denn TableSample gibt nicht wirklich eine zufällige Auswahl von Zeilen zurück. Es weist Ihre Abfrage an, eine Zufallsstichprobe der 8KB-Seiten zu betrachten, aus denen Ihre Zeile besteht. Dann wird Ihre Abfrage anhand der in diesen Seiten enthaltenen Daten ausgeführt. Aufgrund der Art und Weise, wie die Daten auf diesen Seiten gruppiert sein können (Einfügereihenfolge usw.), könnte dies zu Daten führen, die nicht wirklich eine Zufallsstichprobe sind.

Siehe: http://www.mssqltips.com/tip.asp?tip=1308

Diese MSDN-Seite für TableSample enthält ein Beispiel dafür, wie man eine tatsächliche Zufallsstichprobe von Daten erzeugt.

http://msdn.microsoft.com/en-us/library/ms189108.aspx

0voto

Endri Punkte 654

Für SQL Server 2005 und höher, Erweiterung der Antwort von @GreyPanther für die Fälle, in denen num_value hat keine kontinuierlichen Werte. Dies funktioniert auch in Fällen, in denen die Datensätze nicht gleichmäßig verteilt sind und wenn num_value ist keine Zahl, sondern ein eindeutiger Bezeichner.

WITH CTE_Table (SelRow, num_value) 
AS 
(
    SELECT ROW_NUMBER() OVER(ORDER BY ID) AS SelRow, num_value FROM table
) 

SELECT * FROM table Where num_value = ( 
    SELECT TOP 1 num_value FROM CTE_Table  WHERE SelRow >= RAND() * (SELECT MAX(SelRow) FROM CTE_Table)
)

0voto

BlaM Punkte 27550

Ich muss CD-MaN zustimmen: Die Verwendung von "ORDER BY RAND()" eignet sich gut für kleine Tabellen oder wenn Sie Ihr SELECT nur wenige Male ausführen.

Ich verwende auch die Technik "num_value >= RAND() * ...", und wenn ich wirklich zufällige Ergebnisse haben möchte, habe ich eine spezielle "Zufalls"-Spalte in der Tabelle, die ich einmal am Tag oder so aktualisiere. Dieser einzelne UPDATE-Lauf wird einige Zeit in Anspruch nehmen (vor allem, weil Sie einen Index für diese Spalte haben müssen), aber es ist viel schneller als die Erstellung von Zufallszahlen für jede Zeile bei jedem Select-Lauf.

0voto

Kuks Punkte 13
select r.id, r.name from table AS r
INNER JOIN(select CEIL(RAND() * (select MAX(id) from table)) as id) as r1
ON r.id >= r1.id ORDER BY r.id ASC LIMIT 1

Dies erfordert eine geringere Berechnungszeit

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