11

「場所」、「ユーザー」、「バイト」の 3 つのフィールドを持つ単純なテーブルがあるとします。あるフィルターの下で、「場所」ごとにグループ化し、「場所」ごとに、その場所のすべてのバイトを合計し、その場所のユーザーをランダムに選択するとします ( 'where' フィルターと関連する 'place')。「ランダムに選択する」集計関数があった場合、私は次のようにします。

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

...しかし、そのような集計関数は見つかりませんでした。何か不足していますか?これを達成するための良い方法は何でしょうか?

4

4 に答える 4

5

RDBMSが分析機能をサポートしている場合。

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; 

SQL ServerのCrypt_gen_random(4)場合、またはNEWID()の代わりに使用できるものの例になりますrandom_function()

于 2012-11-18T14:34:58.583 に答える
3

あなたの質問はDBMS固有のものだと思います。DBMS が MySql の場合、次のようなソリューションを使用できます。

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;

サブクエリは、ランダムな順序でレコードを並べ替えます。user は集計関数にも group by 句にも含まれていないため、外側のクエリ group by place、 sumsbytesは最初のランダムなユーザーを返します。

于 2012-11-18T15:27:06.917 に答える
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() は乱数を取得する 1 つの方法にすぎません。)

なんらかの理由で、私はこのアプローチを好みます。これは、外側のクエリにまだ集計関数があるためです。多数のフィールドを要約している場合、これは私にとってよりきれいに見えます。

于 2012-11-18T23:24:48.643 に答える