2012-11-18 3 views
8

私は、 'place'、 'user'、 'bytes'の3つのフィールドを持つ単純なテーブルを持っているとします。あるフィルタでは、「場所」と各「場所」でグループ化して、その場所のすべてのバイトを合計し、その場所のユーザーをランダムに選択したいとします。 'where'フィルタと関連する 'place')。SQL random aggregate

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

を...しかし、私はそのような集約関数を見つけることができませんでした:集約関数「からランダムに選択」があった場合、私はどうなります。何か不足していますか?これを達成するには何が良い方法でしょうか?

+4

これはどのRDBMSですか? –

+0

私はそのような機能を持つ個々のRDBMSを認識していません。ほとんどの場合、同じ結果を得るために他のメカニズムを使用する必要があります。*各ユーザーにランダムな番号を割り当てた後、最高の値を持つユーザーを選ぶなど)*ただし、それぞれの機能は異なり、それぞれが異なる動作をします。だから、これは本当にRDBMS固有の質問です。 – MatBailie

+0

MySQLを使用している場合は、誤った 'GROUP BY'を書いてください(例えば、ユーザに集計を適用しないでください)、ランダムに行を選択します。 –

答えて

5

RDBMSが分析機能をサポートしている場合。 SQL ServerのCrypt_gen_random(4)またはNEWID()については

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; 

random_function()

2

ためで置き換えることができる何かの例だろう、私はあなたの質問は、DBMSの特定のだと思います。ランダムな順序で

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; 

サブクエリの受注レコード:あなたのDBMSは、MySQLの場合、あなたはこのようなソリューションを使用することができます。外部クエリグループplaceは、合計がbytesであり、ユーザーが集計関数には属しておらず、group by句でもないため、最初のランダムユーザーを返します。

私はマーティンのソリューションに変化のビットを行うだろう
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 

いくつかのために

を(NEWID()は、データベースに依存し、乱数を取得するためのひとつの方法であるところ。)理由は、外側のクエリにはまだ集計関数があるので、私はこのアプローチを好む。あなたがフィールドの束を要約しているなら、これは私にとってはより清潔に思えます。カスタム集計関数になり

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

SELECT_AT_RAMDOM

0

カスタム集計関数を使用すると、同じくらい簡単として式を書くことができます。

an implementationであり、PostgreSQLです。