2

select a, b, [...];結果を返すselect ステートメントがあります。

a|b
---------
1|8688798
2|355744
4|457437
7|27834

私はそれを返したい:

a|b
---------
1|8688798
2|355744
3|0
4|457437
5|0
6|0
7|27834

ギャップ番号がないため、私が望むことをしないクエリの例:

select
    sub.num_of_ratings,
    count(sub.rater)
from
(
    select 
        r.rater_id as rater,
        count(r.id) as num_of_ratings
    from ratings r
    group by rater
) as sub
group by num_of_ratings;

クエリの説明: ユーザーが別のユーザーを評価すると、その評価が評価テーブルにリストされ、評価ユーザーの ID がフィールド rater_id に保持されます。事実上、評価で参照されているすべてのユーザーをチェックし、そのユーザーについて見つかった評価レコードの数を数えますrater / num_of_ratings

最後に、1 回評価したユーザー数、2 回評価したユーザー数などがわかります。私の問題は、count(sub.rater) の数値が 1,2,3,4,5 から正常に始まることです...ただし、数字が大きいほどギャップがあります。これは、1028 回評価したユーザーが 1 人いて、1027 回評価したユーザーがいない可能性があるためです。

結果をループするストアドプロシージャなどを適用したくありません。ストアド プロシージャを使用したり、ループしたり、一時テーブルを作成したりせずに、結果のギャップを埋めることは可能ですか?

4

3 に答える 3

3

一連の数字がある場合は、そのテーブルで JOIN を実行して、ギャップを適切に埋めることができます。

シーケンスを取得する方法に関するこの質問を確認できます: MySQL で整数シーケンスを生成する

以下は、1 から 10,000 までの数値を生成するという制限で簡単に使用できる、投稿された回答の 1 つです。

SELECT @row := @row + 1 as row FROM 
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t,
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t2, 
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t3, 
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t4, 
(SELECT @row:=0) t5
于 2012-06-21T15:45:50.150 に答える
0

@mazzucci:クエリは魔法のようで、実際にはクエリを説明していません。

@David:その目的のためにテーブルを作成することはできません(質問で述べられているように)

基本的に私が必要としているのは、ギャップのない数値のリストを返すselectです。次に、その結​​果セットに結合したままにして、NULLを0として扱うことができます。

必要なのは、最終リストの長さよりも多くのレコードを保持する任意のテーブルです。次の例では、そのためにテーブルユーザーを使用します。

select @row := @row + 1 as index
    from (select @row := -1) r, users u
limit 101;

このクエリは、0から100までの数値のセットを返します。これを左結合のサブクエリとして使用すると、最終的にギャップが埋められます。

ユーザーは、リレーショナルエンジンを稼働させ続けるための単なるダミーであり、したがって、数値を段階的に生成します。

select t1.index as a, ifnull(t2.b, 0) as b
from (
    select @row := @row + 1 as index
        from (select @row := 0) r, users u
    limit 7
) as t1
left join (
    select a, b [...]
) as t2
on t1.index = t2.a;

私はこのクエリをライブで試していなかったので、少し欠陥があれば私と一緒に慈悲を持ってください。しかし、技術的には機能します。あなたは私のポイントを取得します。

編集:

この概念を使用して、結合メジャーを残す日付のギャップのないリストを取得しました。

select @date := date_add(@date, interval 1 day) as date
    from (select @date := '2010-10-14') d, users u
limit 700

2010/10/15から開始し、さらに699日を繰り返します。

于 2012-07-03T10:00:02.507 に答える
0

一連の数字を使用して、結果セットを結合できます。たとえば、数値リストが numbersList というテーブルにあり、列番号が次のようになっているとします。

Select number, Count 
from
  numbersList left outer join
  (select
      sub.num_of_ratings,
      count(sub.rater) as Count
  from
  (
      select 
          r.rater_id as rater,
          count(r.id) as num_of_ratings
      from ratings r
      group by rater
  ) as sub
  group by num_of_ratings) as num

on num.num_of_ratings=numbersList.number
where numbersList.number<max(num.num_of_ratings) 

数値リストは明らかに最大値よりも大きくなければならず、制限により、すべての数値が最大値に達しないことが許可されます。(MySQL がそのタイプの where 句を許可しない場合は、where 句を省略してすべての数値を最大数までリストするか、さまざまな方法でクエリを変更して同じ結果を得ることができます。)

于 2012-06-21T17:20:17.203 に答える