SQL'de rastgele bir satır nasıl istenir?


510

Saf SQL'de nasıl rastgele bir satır (veya mümkün olduğu kadar gerçekten rastgele yakın) isteyebilirim?


Ben sql sorgu sonuçları sonra her zaman php bunu yapmak için kullanılır ... Bu muhtemelen çözümün limit 1 eki göre işleme için çok daha hızlı
CheeseConQueso


2
Her dbms üzerinde çalışan "saf SQL" çözümü yok gibi görünüyor ... her biri için bir çözüm var.
Manu

Yanıtlar:


735

Şu gönderiye bakın: SQL - Veritabanı tablosundan rastgele bir satır seçmek . Bunu MySQL, PostgreSQL, Microsoft SQL Server, IBM DB2 ve Oracle'da yapmak için yöntemlerden geçer (bu bağlantıdan aşağıdakiler kopyalanır):

MySQL ile rastgele bir satır seçin:

SELECT column FROM table
ORDER BY RAND()
LIMIT 1

PostgreSQL ile rastgele bir satır seçin:

SELECT column FROM table
ORDER BY RANDOM()
LIMIT 1

Microsoft SQL Server ile rastgele bir satır seçin:

SELECT TOP 1 column FROM table
ORDER BY NEWID()

IBM DB2 ile rastgele bir satır seçin

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

Oracle ile rastgele bir kayıt seçin:

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

30
order by rand()Tüm dbs'ye güvenmek veya eşdeğerleri için -1 : |. burada da bahsedildi .
AD7six

20
On yıl önce bir adam kullanmanın ORDER BY RAND()yanlış olduğunu söyledi ...
trejder

SQL Server'da ORDER BY NEWID () oldukça yavaş görünüyor. Sorgum şöyle: Müşteri C iç birleşiminden top 1000 C.CustomerId, CL.LoginName öğesini seçin. C.CustomerId = CL'deki MüşteriGiriş CL'sindeki C. NEWID () tarafından count (*)> 1 sıraya sahip LoginName "NEWID () by order) satırının kaldırılması sonuçları çok daha hızlı döndürür.
Ben Power

3
SQLite için RANDOM () işlevini kullanın.
Slam

10
Bu çözümler ölçeklenmiyor. Bunlar O(n)ile ntablodaki kayıtların sayısı olmak. 1 milyon kaydınız olduğunu düşünün, gerçekten 1 milyon rastgele numara veya benzersiz kimlik oluşturmak istiyor musunuz? Bunu tek bir rastgele sayıyla COUNT()yeni bir LIMITifadeye kullanmayı tercih ederim .
Christian Hujer

174

Jeremies gibi çözümler:

SELECT * FROM table ORDER BY RAND() LIMIT 1

ancak tüm tabloların sıralı olarak taranması gerekir (çünkü her satırla ilişkili rastgele değerin hesaplanması gerekir - böylece en küçük olanı belirlenebilir), bu da orta boy tablolar için oldukça yavaş olabilir. Benim tavsiyem bir çeşit indekslenmiş sayısal sütun kullanmak (birçok tablonun bunlar birincil anahtarları olarak var) ve daha sonra şöyle bir şey yazmanız:

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

num_valueİndekslenmişse , tablo boyutundan bağımsız olarak logaritmik zamanda çalışır . Bir uyarı: bu num_value, aralıkta eşit olarak dağıtıldığını varsayar 0..MAX(num_value). Veri kümeniz bu varsayımdan güçlü bir şekilde saparsa, çarpık sonuçlar alırsınız (bazı satırlar diğerlerinden daha sık görünür).


8
İkinci öneri rastgele değildir. Seçilecek satırı tahmin edemezsiniz, ancak bahis yapmak zorunda olsaydınız, ikinci sırada bahis oynarsınız. Ve asla son satıra bahis oynamazsınız, num_value değerinizin dağılımı ve tablonuzun büyüklüğü ne olursa olsun seçilme olasılığı azalır.
Etienne Racine

1
Genellikle RAND () işlevlerinin çok yüksek kalitede olmadığını biliyorum, ancak bunun dışında neden seçimin rastgele olmayacağını ayrıntılı olarak açıklayabilirsiniz?
Grey Panther

13
İlki SQL Server'da YANLIŞ. RAND () işlevi sorgu başına yalnızca bir kez çağrılır, satır başına bir kez değil. Bu yüzden her zaman ilk satırı seçer (deneyin).
Jeff Walker Code Ranger

3
İkincisi ayrıca tüm satırların muhasebeleştirildiğini varsayar: silinen bir satır seçmesi mümkündür.
Sam Rueby

3
@ Sam.Rueby Aslında, num_value> = RAND () ... limit 1, boş satırların mevcut satır bulunana kadar atlanmasını sağlar.
ghord

62

Bunun ne kadar verimli olduğunu bilmiyorum, ama daha önce kullandım:

SELECT TOP 1 * FROM MyTable ORDER BY newid()

GUID'ler oldukça rasgele olduğundan, sıralama rastgele bir satır elde edeceğiniz anlamına gelir.


1
MS SQL sunucusu kullanıyorum, TOP 1 * FROM some_table_name ORDER BY NEWID () benim için harika çalıştı, tavsiye çocuklar için teşekkürler!

Bu tam olarak aynı şeyORDER BY RAND() LIMIT 1
Ken Bloom

6
Bu da TOP 1ve veritabanını kullandığından veritabanına özeldir newid().
Gri

12
Bu kötü bir fikir. Her sütun bağımsız olarak dizine eklenmediği sürece bu yöntem bir dizin kullanmaz. 100 milyon kayıt içeren tablonun bir kayıt alması çok uzun sürebilir.
Anahtarı

1
@Switch ve hangi çözümü önerirsiniz?
Akmal Salikhov

31
ORDER BY NEWID()

alır 7.4 milliseconds

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

alır 0.0065 milliseconds!

Kesinlikle ikinci yöntemle gideceğim.


2
İkinci seçenek son satırı seçmez. Neden bilmiyorum - sadece işaret ediyor.
Voldemort

7
@Voldemort: burada rand()bir kayan nokta sayısı döndürür . Bir tamsayı varsayarsak , dönüş değeri de bir tamsayıya zorlanır, böylece ondalık noktadan sonra herhangi bir şeyi keser. Bu nedenle, daima daha az olacaktır , bu yüzden son satır asla seçilmeyecektir. n0 < n < 1num_valuerand() * max(num_value)rand() * max(num_value)max(num_value)
Ian Kemp

Verilerim sık sık silinirse verimli olmayacağım - bir boşluk bulursam, tüm sorguyu yeniden çalıştırmam gerekir.
Loic Coenen

1
@IanKemp Aptalca soru, öyleyse neden SELECT MAX (num_value) + 1 ?? Rand (veya çoğu durumda RANDOM) [0,1) döndürdüğünden, tüm değer aralığını elde edersiniz. Ayrıca, evet, haklısın, bir sorguyu düzeltmelisin.
tekHedd

13

Hangi sunucuyu kullandığınızı söylemediniz. SQL Server'ın eski sürümlerinde şunları kullanabilirsiniz:

select top 1 * from mytable order by newid()

SQL Server 2005 ve sonraki TABLESAMPLEsürümlerde, tekrarlanabilir rastgele bir örnek almak için kullanabilirsiniz :

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

9
MSDN, gerçekten rastgele sonuçlar için newid () yönteminin örnek olarak tercih edildiğini söylüyor: msdn.microsoft.com/en-us/library/ms189108.aspx
Andrew Hedges

7
@Andrew Hedges: ORDER BY NEWID () çok
pahalı

10

SQL Server için

newid () / order by işe yarayacaktır, ancak her satır için bir kimlik oluşturması ve ardından bunları sıralaması gerektiği için büyük sonuç kümeleri için çok pahalı olacaktır.

TABLESAMPLE (), performans açısından iyidir, ancak sonuçların toplanmasını sağlarsınız (sayfadaki tüm satırlar döndürülür).

Daha iyi performans gösteren gerçek bir rastgele örnek için en iyi yol, satırları rastgele filtrelemektir. Aşağıdaki kod örneğini TABLESAMPLE kullanarak sonuç kümelerini sınırlama SQL Server Books Online'da buldum :

Gerçekten tek tek sıraların rastgele bir örneğini istiyorsanız, TABLESAMPLE yerine satırları rastgele filtrelemek için sorgunuzu değiştirin. Örneğin, aşağıdaki sorgu, Sales.SalesOrderDetail tablosundaki satırların yaklaşık yüzde birini döndürmek için NEWID işlevini kullanır:

SELECT * FROM Sales.SalesOrderDetail
WHERE 0.01 >= CAST(CHECKSUM(NEWID(),SalesOrderID) & 0x7fffffff AS float)
              / CAST (0x7fffffff AS int)

SalesOrderID sütunu CHECKSUM ifadesine dahil edilir, böylece NEWID () satır başına örnekleme elde etmek için satır başına bir kez değerlendirilir. CAST (CHECKSUM (NEWID (), SalesOrderID) & 0x7fffffff AS float / CAST (0x7fffffff AS int) ifadesi 0 ile 1 arasında rastgele bir float değeri olarak değerlendirilir.

1.000.000 sıralı bir tabloya karşı çalıştırıldığında, sonuçlarım şöyle:

SET STATISTICS TIME ON
SET STATISTICS IO ON

/* newid()
   rows returned: 10000
   logical reads: 3359
   CPU time: 3312 ms
   elapsed time = 3359 ms
*/
SELECT TOP 1 PERCENT Number
FROM Numbers
ORDER BY newid()

/* TABLESAMPLE
   rows returned: 9269 (varies)
   logical reads: 32
   CPU time: 0 ms
   elapsed time: 5 ms
*/
SELECT Number
FROM Numbers
TABLESAMPLE (1 PERCENT)

/* Filter
   rows returned: 9994 (varies)
   logical reads: 3359
   CPU time: 641 ms
   elapsed time: 627 ms
*/    
SELECT Number
FROM Numbers
WHERE 0.01 >= CAST(CHECKSUM(NEWID(), Number) & 0x7fffffff AS float) 
              / CAST (0x7fffffff AS int)

SET STATISTICS IO OFF
SET STATISTICS TIME OFF

TABLESAMPLE'ı kullanmaktan kurtulabilirseniz, size en iyi performansı verecektir. Aksi takdirde newid () / filter yöntemini kullanın. büyük bir sonuç kümeniz varsa newid () / order by son çare olmalıdır.


4

Mümkünse, RND () üzerindeki her iki dizinin verimsizliğini ve kayıt numarası alanı oluşturmayı önlemek için saklı ifadeleri kullanın.

"SELECT * tablo LIMIT?, 1" 'den RandomRecord HAZIRLAYIN;
SET @ n = ZEMİN (RAND () * (Tablodan COUNT (*) SEÇ));
YÜRÜT Rastgele Kayıt @ n;

Bu çözüm ayrıca, yukarıdaki maddede kullanılan dizinlenmiş sayısal değer eşit olarak dağıtılmadığında rasgele satırların döndürülmesiyle de ilgilenir; bu nedenle id_value> = RAND () * MAX (id_value) işlevini kullanmakla neredeyse aynı (sabit) zaman alsa bile, daha iyidir.
guido

Bunun sabit zamanda çalışmadığını söyleyebildiğim kadarıyla, doğrusal zamanda çalışır. En kötü durumda, @n, tablodaki satır sayısına eşittir ve "SELECT * FROM table LIMIT?, 1", son satırına ulaşıncaya kadar @n - 1 satırı değerlendirir.
Andres Riofrio

3

En iyi yol, sadece bu amaçla yeni bir sütuna rastgele bir değer koymak ve bunun gibi bir şey kullanmaktır (sahte kod + SQL):

randomNo = random()
execSql("SELECT TOP 1 * FROM MyTable WHERE MyTable.Randomness > $randomNo")

Bu MediaWiki kodu tarafından kullanılan çözümdür. Elbette, daha küçük değerlere karşı bazı önyargılar vardır, ancak hiçbir satır getirilmediğinde rastgele değerin sıfıra sarılmasının yeterli olduğunu bulmuşlardır.

newid () çözümü tam tablo taraması gerektirebilir, böylece her satıra daha az performans gösterecek yeni bir kılavuz atanabilir.

rand () çözümü hiç çalışmayabilir (yani MSSQL ile), çünkü fonksiyon sadece bir kez değerlendirilecek ve her satıra aynı "rastgele" sayı atanacaktır.


1
0 sonuç aldığınızda etrafa sarılmak makul bir rastgele örnek sağlar (sadece "yeterince iyi" değil). Bu çözüm neredeyse çok satırlı sorgulara ölçeklendirilir ("parti karışıklığı" nı düşünün). Sorun, sonuçların aynı gruplarda tekrar tekrar seçilme eğiliminde olmasıdır. Bu sorunu çözmek için, az önce kullandığınız rasgele sayıları yeniden dağıtmanız gerekir. RandomNo'yu takip ederek ve sonuçlardan maksimum (rasgele) olarak ayarlayarak hile yapabilirsiniz, ancak daha sonra p (sorgu 1'de satır i ve sorgu 2'de satır i) = = 0, bu adil değil. Biraz matematik yapmama izin verin, size gerçekten adil bir planla döneceğim.
alsuren

3

SQL Server 2005 ve 2008 için, münferit satırların rastgele bir örneğini istiyorsak ( Books Online'dan ):

SELECT * FROM Sales.SalesOrderDetail
WHERE 0.01 >= CAST(CHECKSUM(NEWID(), SalesOrderID) & 0x7fffffff AS float)
/ CAST (0x7fffffff AS int)

3

Teşvik edilmediğinden, RAND () kullanıldığında ısrarlı bir şekilde maksimum ID (= Maks) alabilirsiniz:

SELECT MAX(ID) FROM TABLE;

1.Maks (= My_Generated_Random) arasında rastgele

My_Generated_Random = rand_in_your_programming_lang_function(1..Max);

ve sonra bu SQL'i çalıştırın:

SELECT ID FROM TABLE WHERE ID >= My_Generated_Random ORDER BY ID LIMIT 1

Kimlikleri seçilen değerden EQUAL veya HIGHER olan satırları kontrol edeceğini unutmayın. Tablodaki satır için avlamak ve My_Generated_Random'dan eşit veya daha düşük bir kimlik almak ve ardından sorguyu şu şekilde değiştirmek de mümkündür:

SELECT ID FROM TABLE WHERE ID <= My_Generated_Random ORDER BY ID DESC LIMIT 1

Oluşturulan rasgele kimlik artık tabloda mevcut değilse ne olur? Kullanıcıya göstermek istemediğiniz silinen veya pasif satırlar sorun yaratacaktır.
Ebleme

Hiçbir şey değil. Kesin değil, kimlik numarasını KAPALI alırsınız. İd = 1 öğesinin kaldırılacağını düşünüyorsanız 1 ile minimum alışverişi yapın.
forsberg

2

@ BillKarwin'in @ cnu'nun cevabı hakkındaki yorumunda belirtildiği gibi ...

Bir LIMIT ile birleştirirken, gerçek satırları doğrudan sipariş etmek yerine rastgele bir siparişle JOIN'e (en azından PostgreSQL 9.1 ile) çok daha iyi performans gösterdiğini gördüm:

SELECT * FROM tbl_post AS t
JOIN ...
JOIN ( SELECT id, CAST(-2147483648 * RANDOM() AS integer) AS rand
       FROM tbl_post
       WHERE create_time >= 1349928000
     ) r ON r.id = t.id
WHERE create_time >= 1349928000 AND ...
ORDER BY r.rand
LIMIT 100

'R' değerinin, birleştirilen karmaşık sorgudaki olası her anahtar değer için bir 'rand' değeri oluşturduğundan emin olun, ancak yine de mümkünse 'r' satır sayısını sınırlandırın.

Tamsayı olarak CAST, tamsayı ve tek duyarlıklı kayan türler için özel sıralama optimizasyonuna sahip PostgreSQL 9.2 için özellikle yararlıdır.


1

Buradaki çözümlerin çoğu sıralamadan kaçınmayı amaçlamaktadır, ancak yine de bir tablo üzerinde sıralı bir tarama yapmaları gerekir.

İndeks taramaya geçerek sıralı taramayı önlemenin bir yolu da vardır. Rastgele satırınızın dizin değerini biliyorsanız, sonucu neredeyse anında alabilirsiniz. Sorun - bir dizin değeri nasıl tahmin edilir.

Aşağıdaki çözüm PostgreSQL 8.4 üzerinde çalışır:

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;

Ben çözüm yukarıdaki 0 ​​aralığı 10 farklı rasgele dizin değerleri tahmin .. .. id son değeri].

10 sayısı isteğe bağlıdır - 100 veya 1000 kullanabilirsiniz (şaşırtıcı bir şekilde) yanıt süresi üzerinde büyük bir etkisi yoktur.

Ayrıca bir sorun var - seyrek kimlikleri varsa, kaçırabilirsiniz . Çözüm bir yedekleme planına sahip olmaktır :) Bu durumda random () sorgu ile saf eski bir düzen. Birleşik kimlik şöyle göründüğünde:

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;

Değil birlik TÜM fıkra. Bu durumda, ilk bölüm herhangi bir veri döndürürse, ikinci bölüm ASLA yürütülmez!


1

Geç kaldım, ancak Google üzerinden buraya geldim, bu yüzden gelecek kuşaklar için alternatif bir çözüm ekleyeceğim.

Başka bir yaklaşım, TOP'u iki kez alternatif sırayla kullanmaktır. "Saf SQL" olup olmadığını bilmiyorum, çünkü TOP bir değişken kullanıyor, ancak SQL Server 2008'de çalışıyor. İşte rastgele bir kelime istiyorsanız, sözlük kelimelerin bir tablo karşı kullandığım bir örnek.

SELECT TOP 1
  word
FROM (
  SELECT TOP(@idx)
    word 
  FROM
    dbo.DictionaryAbridged WITH(NOLOCK)
  ORDER BY
    word DESC
) AS D
ORDER BY
  word ASC

Tabii ki, @idx, hedef tablodaki 1 ile COUNT (*) arasında değişen rasgele oluşturulmuş bir tamsayıdır. Sütununuz dizine eklenmişse, bundan da yararlanacaksınız. Başka bir avantaj da NEWID () işlevine izin verilmediğinden, onu bir işlevde kullanabilmenizdir.

Son olarak, yukarıdaki sorgu aynı tabloda bir NEWID () tipi sorgu türünün yürütme süresinin yaklaşık 1 / 10'unda çalışır. YYMV.



1

MySQL'in rastgele kayıt alması

 SELECT name
  FROM random AS r1 JOIN
       (SELECT (RAND() *
                     (SELECT MAX(id)
                        FROM random)) AS id)
        AS r2
 WHERE r1.id >= r2.id
 ORDER BY r1.id ASC
 LIMIT 1

Daha fazla ayrıntı http://jan.kneschke.de/projects/mysql/order-by-rand/


Cevapların çoğunu test ettikten sonra bunun en iyisi olduğuna inanıyorum. Hızlı görünüyor ve her seferinde iyi bir rastgele sayı seçiyor. @GreyPanther'in yukarıdaki ikinci önerisine benziyor, ancak bu cevap daha rastgele sayılar alıyor.
Jeff Baker

1

Cevaplarda bu varyasyonu henüz görmedim. Her seferinde aynı satır kümesini seçmek için bir başlangıç ​​tohumu verildiğinde ek bir kısıtlama vardı.

MS SQL için:

Minimum örnek:

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

Normalleştirilmiş yürütme süresi: 1.00

NewId () örneği:

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

Normalleştirilmiş yürütme süresi: 1.02

NewId()önemsiz derecede yavaş olduğundan rand(checksum(*))büyük kayıt kümelerine karşı kullanmak istemeyebilirsiniz.

İlk Tohumlu Seçim:

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 */

Bir tohum verilen aynı seti seçmeniz gerekiyorsa, bu işe yarıyor gibi görünüyor.


1

MSSQL'de (11.0.5569'da test edilmiştir)

SELECT TOP 100 * FROM employee ORDER BY CRYPT_GEN_RANDOM(10)

önemli ölçüde daha hızlı

SELECT TOP 100 * FROM employee ORDER BY NEWID()

1

SQL Server'da, oldukça iyi bir rastgelelik elde etmek ve hala hız elde etmek için TABLESAMPLE komutunu NEWID () ile birleştirebilirsiniz. Bu, özellikle yalnızca 1 veya az sayıda satır istiyorsanız faydalıdır.

SELECT TOP 1 * FROM [table] 
TABLESAMPLE (500 ROWS) 
ORDER BY NEWID()

1

SQL Server 2012+ ile bunu tek bir rastgele satır için yapmak için OFFSET FETCH sorgusunu kullanabilirsiniz

select  * from MyTable ORDER BY id OFFSET n ROW FETCH NEXT 1 ROWS ONLY

burada id bir kimlik sütunudur ve n, istediğiniz satırdır - tablonun 0 ile count () - 1 arasında rastgele bir sayı olarak hesaplanır (0 değeri, her şeyden önce ilk satırdır)

ORDER BY deyimi için çalışmak için bir dizin olduğu sürece, tablo verilerinde deliklerle çalışır. Rastgele olma için de çok iyidir - kendinizi dışarı aktarmak için çalışırken, ancak diğer yöntemlerde niggles mevcut değildir. Buna ek olarak, performans oldukça iyi, daha küçük bir veri kümesinde iyi duruyor, ancak birkaç milyon satıra karşı ciddi performans testleri denemedim.



0

CD-MaN ile anlaşmak zorundayım: "ORDER BY RAND ()" kullanarak küçük tablolar için veya SELECT'inizi sadece birkaç kez yaptığınızda iyi çalışır.

Ayrıca "num_value> = RAND () * ..." tekniğini kullanıyorum ve gerçekten rastgele sonuçlar elde etmek istiyorsam, günde bir kez güncellediğim tabloda özel bir "rastgele" sütun var. Bu tek UPDATE çalıştırması biraz zaman alacaktır (özellikle bu sütunda bir dizin olması gerektiğinden), ancak seçim her çalıştırıldığında her satır için rastgele sayılar oluşturmaktan çok daha hızlıdır.


0

Dikkatli olun çünkü TableSample aslında rastgele bir satır örneği döndürmez. Sorgunuzu, satırınızı oluşturan 8 KB'lik sayfaların rastgele bir örneğine bakmaya yönlendirir. Ardından, sorgunuz bu sayfalarda bulunan verilere karşı yürütülür. Verilerin bu sayfalarda nasıl gruplanabileceğinden (ekleme sırası vb.), Bu aslında rastgele bir örnek olmayan verilere yol açabilir.

Bkz. Http://www.mssqltips.com/tip.asp?tip=1308

TableSample için bu MSDN sayfası, gerçekte rastgele bir veri örneğinin nasıl oluşturulacağına ilişkin bir örnek içerir.

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


0

Listelenen fikirlerin çoğu hala sipariş kullanıyor

Ancak, geçici bir tablo kullanırsanız, rastgele bir dizin atayabilirsiniz (çözümlerin çoğunun önerdiği gibi) ve sonra 0 ile 1 arasında rasgele bir sayıdan büyük olan ilk tabloyu alabilirsiniz.

Örneğin (DB2 için):

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

2
Bu çözümü düşündükten sonra, mantığımda temel bir kusur buldum. Bu, tablonun başlangıcına yakın bir şekilde aynı küçük kurulum değerlerini döndürür, çünkü 0 ile 1 arasında eşit dağılım varsa, ilk satırın bu kriterleri karşılama şansının% 50 olduğunu varsayarım.
DAVID


0

Dbms_random.value kullanmak yerine Oracle için daha iyi bir çözüm vardır, dbms_random.value ile satır sipariş etmek için tam tarama gerektirir ve büyük tablolar için oldukça yavaştır.

Bunun yerine şunu kullanın:

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

0

Firebird için:

Select FIRST 1 column from table ORDER BY RAND()

0

SQL Server 2005 ve üstü için, num_valuesürekli değerleri olmayan durumlarda @ GreyPanther'ın cevabını genişletmek . Bu, veri kümelerini eşit olarak dağıtmadığımız ve num_valuebir sayı değil, benzersiz bir tanımlayıcı olduğunda da işe yarar .

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

-1

Sql'den rastgele işlev yardımcı olabilir. Ayrıca yalnızca bir satırla sınırlamak istiyorsanız, bunu sonuna ekleyin.

SELECT column FROM table
ORDER BY RAND()
LIMIT 1
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.