Oracle DB'den rasgele satır seçmem gerekiyor.
Ör: 100 satırlık bir tablo varsayın, bu kayıtların 20'sini 100 satırın tamamından rastgele nasıl döndürebilirim.
Yanıtlar:
SELECT *
FROM (
SELECT *
FROM table
ORDER BY DBMS_RANDOM.RANDOM)
WHERE rownum < 21;
SAMPLE () öğesinin size tam olarak 20 satır vereceği garanti edilmez , ancak uygun olabilir (ve büyük tablolar için tam bir sorgu + rasgele sırala göre önemli ölçüde daha iyi performans gösterebilir):
SELECT *
FROM table SAMPLE(20);
Not: 20
Burada istenen satır sayısı değil, yaklaşık bir yüzde verilmiştir. Bu durumda, 100 satırınız olduğundan, yaklaşık 20 satır elde etmek için% 20'lik bir örnek istersiniz.
SELECT * FROM table SAMPLE(10) WHERE ROWNUM <= 20;
Tabloyu sıralaması gerekmediği için bu daha verimlidir.
20 sırayı rastgele seçmek için bence bunların çoğunu rastgele sırayla seçip bu setin ilk 20'sini seçmeniz daha iyi olur.
Gibi bir şey:
Select *
from (select *
from table
order by dbms_random.value) -- you can also use DBMS_RANDOM.RANDOM
where rownum < 21;
Küçük tablolar için, yalnızca çoğunu atmak için büyük veri yığınlarını seçmekten kaçınmak için kullanılır.
Özetle, iki yol tanıtıldı
1) using order by DBMS_RANDOM.VALUE clause
2) using sample([%]) function
Birinci yolun 'DOĞRULUK' avantajına sahiptir, bu da gerçekten varsa sonuç almada asla başarısız olmayacağınız anlamına gelirken, ikinci yöntemde, örnekleme sırasında bilgi azaldığından sorgu koşulunu karşılayan durumlar olsa bile sonuç alamazsınız.
İkinci yolun 'ETKİLİ' avantajı vardır, bu da daha hızlı sonuç alacağınız ve veri tabanınıza hafif yük vereceğiniz anlamına gelir. DBA'dan ilk yolu kullanan sorgumun veritabanına yükler verdiğine dair bir uyarı aldım
İlginize göre iki yoldan birini seçebilirsiniz!
Büyük tablolar söz konusu olduğunda, dbms_random.value'ya göre sıralama ile standart yol etkili değildir çünkü tüm tabloyu taramanız gerekir ve dbms_random.value oldukça yavaş bir işlevdir ve bağlam anahtarları gerektirir. Bu tür durumlar için 3 ek yöntem vardır:
1: Kullanım sample
maddesi:
Örneğin:
select *
from s1 sample block(1)
order by dbms_random.value
fetch first 1 rows only
yani, tüm blokların% 1'ini alın, sonra bunları rastgele sıralayın ve yalnızca 1 satır döndürün.
2: normal dağılıma sahip sütunda bir dizin / birincil anahtarınız varsa varsa, minimum ve maksimum değerleri alabilir, bu aralıkta rastgele değer alabilir ve rastgele oluşturulan bu değerden daha büyük veya ona eşit bir değere sahip ilk satırı elde edebilirsiniz.
Misal:
--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: rastgele tablo bloğu alın, satır kimliği oluşturun ve bu satır kimliği ile tablodan satır alın :
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
)
);
Her gruptan rastgele bir örnek seçmenin yolu:
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;
Ne kadar verimli olduğundan emin değilim, ancak çok sayıda kategori ve alt kategoriniz varsa, bu işi iyi yapıyor gibi görünüyor.
masa
SELECT * FROM
(
SELECT column_name FROM table_name
ORDER BY dbms_random.value
)
WHERE rownum = 1;