2012-11-18 19 views
8

3 alanlı basit bir tablom var: 'place', 'user' ve 'bytes'. Diyelim ki, bazı filtreler altında, 'yer' ile ve her bir yer için, o yer için tüm baytları toplamak ve o mekana rastgele bir kullanıcı seçmek için rastgele seçim yapmak istiyorum. 'nerede' filtre ve ilgili 'yer').SQL rastgele topak

SELECT place, SUM(bytes), SELECT_AT_RANDOM(user) WHERE .... GROUP BY place; 

... ama böyle bir toplama işlevi bulamadık: Bir toplama işlevi "rastgele seçmek" olsaydı, yapardım. Bir şey mi eksik? Bunu başarmak için iyi bir yol ne olabilir?

+4

Bu ne RDBMS? –

+0

Böyle bir işlevi olan herhangi bir bireysel RDBMS'nin farkında değilim. Çoğu aynı sonucu elde etmek için başka bir mekanizma kullanmalıdır * (Her kullanıcıya rasgele bir sayı atamak, ardından kullanıcıyı en yüksek değerle seçmek gibi.) * Fakat her birinin farklı yetenekleri olacaktır ve her biri farklı performans gösterecektir. Yani, bu gerçekten RDBMS'ye özgü bir sorudur. – MatBailie

+0

Eğer MySQL kullaniyorsaniz yalnizca bir "GROUP BY" yazin (örnegin bir kullaniciyi kullanmayin) ve rasgele bir satir seçecektir. –

cevap

5

RDBMS'niz analitik işlevleri destekliyorsa. SQL Server Crypt_gen_random(4) için

WITH T 
    AS (SELECT place, 
       Sum(bytes) OVER (PARTITION BY place) AS Sum_bytes, 
       user, 
       Row_number() OVER (PARTITION BY place ORDER BY random_function()) AS RN 
     FROM YourTable 
     WHERE ....) 
SELECT place, 
     Sum_bytes, 
     user 
FROM T 
WHERE RN = 1; 

veya NEWID()random_function()

2

için ikame edilebilir bir şey örnekleridir olacağını ben soru DBMS özgü olduğunu düşünüyorum. rasgele sırada

SELECT place_rand.place, SUM(place_rand.bytes), place_rand.user as random_user 
FROM 
    (SELECT place, bytes, user 
    FROM place 
    WHERE ... 
    ORDER BY rand()) place_rand 
GROUP BY 
    place_rand.place; 

alt sorgu siparişler kayıtları: En DBMS MySQL ise, böyle bir çözümü kullanabilirsiniz. place tarafından dış sorgu grupları, bytes toplamıdır ve kullanıcı bir toplu işlevde olmadığından ve grup tarafından yan tümcelere göre ilk rastgele kullanıcı döndürür.

Martin'in çözümüne bir varyasyon biraz yapacağını
0

:

select place, sum(bytes), max(case when seqnum = 1 then user end) as random_user 
from (select place, bytes, 
      row_number() over (partition by place order by newid()) as sequm 
     from t 
    ) t 
group by place 

Bazıları için

(newid() veritabanında bağlı rastgele bir sayı almak için sadece bir yolu olduğu yere.) Nedeni, bu yaklaşımı tercih ediyorum, çünkü hala dış sorguda toplama işlevi var. Bir grup tarlayı özetliyorsanız, bu bana daha temiz görünüyor.

SELECT place, SUM(bytes), SELECT_AT_RANDOM(user) WHERE .... GROUP BY place; 

SELECT_AT_RAMDOM özel toplama işlevi olacaktır: kadar basit bir özel birleştirilmiş fonksiyonla