Ich muss Zeilen zufällig aus einer Oracle-Datenbank auswählen.
Beispiel: Nehmen Sie eine Tabelle mit 100 Zeilen an, wie ich 20 dieser Datensätze aus den gesamten 100 Zeilen zufällig zurückgeben kann.
SELECT *
FROM (
SELECT *
FROM table
ORDER BY DBMS_RANDOM.RANDOM)
WHERE rownum < 21;
SAMPLE () liefert nicht garantiert genau 20 Zeilen, ist jedoch möglicherweise geeignet (und bietet möglicherweise eine deutlich bessere Leistung als eine vollständige Abfrage + zufällige Sortierung für große Tabellen):
SELECT * FROM table SAMPLE(20);
Hinweis: Das
20
hier ist ein ungefährer Prozentsatz, nicht die Anzahl der gewünschten Zeilen. In diesem Fall fordern Sie, da Sie 100 Zeilen haben, eine Stichprobe von 20% an, um ungefähr 20 Zeilen zu erhalten.quelle
SELECT * FROM table SAMPLE(10) WHERE ROWNUM <= 20;
Dies ist effizienter, da die Tabelle nicht sortiert werden muss.
quelle
SELECT column FROM ( SELECT column, dbms_random.value FROM table ORDER BY 2 ) where rownum <= 20;
quelle
Um zufällig 20 Zeilen auszuwählen, ist es meiner Meinung nach besser, die Menge nach dem Zufallsprinzip auszuwählen und die ersten 20 dieses Satzes auszuwählen.
Etwas wie:
Select * from (select * from table order by dbms_random.value) -- you can also use DBMS_RANDOM.RANDOM where rownum < 21;
Am besten für kleine Tabellen geeignet, um zu vermeiden, dass große Datenblöcke ausgewählt werden, nur um das meiste davon zu verwerfen.
quelle
Zusammenfassend wurden zwei Möglichkeiten eingeführt
Der erste Weg hat den Vorteil von 'RICHTIGKEIT', was bedeutet, dass Sie niemals ein Ergebnis erhalten, wenn es tatsächlich vorhanden ist, während Sie auf den zweiten Weg möglicherweise kein Ergebnis erhalten, obwohl Fälle vorliegen, die die Abfragebedingung erfüllen, da die Informationen während der Abtastung reduziert werden.
Der zweite Weg hat den Vorteil von 'EFFIZIENT', was bedeutet, dass Sie schneller Ergebnisse erzielen und Ihre Datenbank leicht belasten. Ich wurde vom DBA gewarnt, dass meine Abfrage auf die erste Weise die Datenbank lädt
Sie können je nach Interesse zwischen zwei Möglichkeiten wählen!
quelle
Bei großen Tabellen ist die Standardmethode mit Sortierung nach dbms_random.value nicht effektiv, da Sie die gesamte Tabelle scannen müssen und dbms_random.value eine ziemlich langsame Funktion ist und Kontextwechsel erfordert. Für solche Fälle gibt es 3 zusätzliche Methoden:
1: Verwenden
sample
:zum Beispiel:
select * from s1 sample block(1) order by dbms_random.value fetch first 1 rows only
dh 1% aller Blöcke erhalten, dann zufällig sortieren und nur 1 Zeile zurückgeben.
2: Wenn Sie einen Index / Primärschlüssel für die Spalte mit normaler Verteilung haben , können Sie Min- und Max-Werte abrufen, Zufallswerte in diesem Bereich abrufen und die erste Zeile mit einem Wert abrufen, der größer oder gleich diesem zufällig generierten Wert ist.
Beispiel:
--big table with 1 mln rows with primary key on ID with normal distribution: Create table s1(id primary key,padding) as select level, rpad('x',100,'x') from dual connect by level<=1e6; select * from s1 where id>=(select dbms_random.value( (select min(id) from s1), (select max(id) from s1) ) from dual) order by id fetch first 1 rows only;
3: Zufälligen Tabellenblock abrufen, Zeilen-ID generieren und Zeile mit dieser Zeilen-ID aus der Tabelle abrufen :
select * from s1 where rowid = ( select DBMS_ROWID.ROWID_CREATE ( 1, objd, file#, block#, 1) from ( select/*+ rule */ file#,block#,objd from v$bh b where b.objd in (select o.data_object_id from user_objects o where object_name='S1' /* table_name */) order by dbms_random.value fetch first 1 rows only ) );
quelle
So wählen Sie aus jeder Gruppe eine Zufallsstichprobe aus:
SELECT GROUPING_COLUMN, MIN (COLUMN_NAME) KEEP (DENSE_RANK FIRST ORDER BY DBMS_RANDOM.VALUE) AS RANDOM_SAMPLE FROM TABLE_NAME GROUP BY GROUPING_COLUMN ORDER BY GROUPING_COLUMN;
Ich bin mir nicht sicher, wie effizient es ist, aber wenn Sie viele Kategorien und Unterkategorien haben, scheint dies die Arbeit gut zu machen.
quelle
Tabelle
Wir haben Lehrertisch
Oracle-Syntax
SELECT * FROM ( SELECT column_name FROM table_name ORDER BY dbms_random.value ) WHERE rownum = 1;
Zum besseren Verständnis folgen Sie dem Screenshot
quelle