web-dev-qa-db-ja.com

mysqlの範囲でグループ化

Table:   
new_table                                                    
user_number  | diff                  
     2       |  0                      
     1       |  28  
     2       |  32  
     1       |  40  
     1       |  53  
     1       |  59  
     1       |  101  
     1       |  105  
     2       |  108  
     2       |  129  
     2       |  130    
     1       |  144  


            |(result)
            v

range  | number of users  
0-20   |  2  
21-41  |  3  
42-62  |  1  
63-83  |  2  
84-104 |  1  
105-135|  0  
136-156|  3


select t.range as [range], count(*) as [number of users]  
from (  
  select case    
    when diff between 0 and 20 then ' 0-20'  
    when diff between 21 and 41 then ' 21-41'  
    when diff between 42 and 62 then ' 42-62'  
    when diff between 63 and 83 then ' 63-83'  
    when diff between 84 and 104 then ' 84-104'  
    when diff between 105 and 135 then ' 105-135'  
    else '136-156'   
     end as range  
  from new_table) t  
group by t.diff  

Error:

You have an error in your SQL syntax, near '[range], count(*) as [number of users]  
from (  
  select case  
    when' at line 1  
15
Compuser7

キーワードの区切り文字としてのMysqlは、角かっこではなく、バッククォート記号 "` "を使用します(SQLサーバーのように)

6
zerkms

Caseステートメントを実行するのはかなり面倒なので、範囲でグループ化する一般的なコードを次に示します。

関数「floor」を使用して範囲の下限を検索し(ボヘミアンが使用した「ラウンド」ではない)、金額(以下の例では19)を追加して範囲の上限を検索できます。範囲の下部と上部が重ならないように注意してください。

mysql> create table new_table (user_number int, diff int);
Query OK, 0 rows affected (0.14 sec)

mysql>  insert into new_table values (2, 0), (1, 28), (2, 32), (1, 40), (1, 53),
        (1, 59), (1, 101), (1, 105), (2, 108), (2, 129), (2, 130), (1, 144);
Query OK, 12 rows affected (0.01 sec)
Records: 12  Duplicates: 0  Warnings: 0

mysql> select concat(21*floor(diff/21), '-', 21*floor(diff/21) + 20) as `range`,
       count(*) as `number of users` from new_table group by 1 order by diff;
+---------+-----------------+
| range   | number of users |
+---------+-----------------+
| 0-20    |               1 |
| 21-41   |               3 |
| 42-62   |               2 |
| 84-104  |               1 |
| 105-125 |               2 |
| 126-146 |               3 |
+---------+-----------------+
6 rows in set (0.01 sec)
40
Josh

これは、あらゆる大きさの差分に対して機能するソリューションです。

select
  concat(21 * round(diff / 21), '-', 21 * round(diff / 21) + 20) as `range`,
  count(*) as `number of users`
from new_table
group by 1
order by diff;

テスト可能なコードとその出力は次のとおりです。

create table new_table (user_number int, diff int);
insert into new_table values (2, 0), (1, 28), (2, 32), (1, 40), (1, 53), (1, 59), (1, 101), (1, 105), (2, 108), (2, 129), (2, 130), (1, 144); 
-- run query, output is: 
+---------+-----------------+
| range   | number of users |
+---------+-----------------+
| 0-20    |               1 |
| 21-41   |               1 |
| 42-62   |               2 |
| 63-83   |               2 |
| 105-125 |               3 |
| 126-146 |               2 |
| 147-167 |               1 |
+---------+-----------------+
8
Bohemian

通常の範囲がある場合、より迅速な解決策はdiv関数を使用してグループ化することです。

例えば:

select diff div 20 as range, sum(user_number)
from new_table
group by diff div 20;

その場合、範囲は1桁で表され、その意味を知っておく必要があります:0 = 0-19、1 = 20-39、2 = 40-59、...

異なる範囲が必要な場合は、異なる除算器を使用するか、差分からいくつかの数値を減算します。たとえば、「(diff --1)div 10」は、範囲1〜10、11〜20、21〜30、..を提供します。

6
nobody

rangeはmysqlキーワードです。 ´を使用して「スケープ」する必要があります:

select t.`range` as [`range`], ...
1
jpereira

1つの明らかな間違い:Mysqlはbackticks(

_`
_

)、_[]_(sqlserverとして)ではありません。 t.range as [range], count(*) as [number of users]をに変更します

_t.range as `range`, count(*) as `number of users`
_
0
a1ex07
select 
case
when diff between 0 and 20 then ' 0-20'
when diff between 0 and 20 then ' 21-41'
when diff between 0 and 20 then ' 42-62'
when diff between 0 and 20 then ' 63-83'
when diff between 0 and 20 then ' 84-104'
when diff between 0 and 20 then ' 105-135'
else '136-156'
end; as 'range',
count(*) as 'number of users'


from new_table
group by range

確認することをお勧めします SQLクエリで角かっこは有効ですか?

'['と ']'はMicrosoftのSQLで使用されているが、mysqlでは使用されていないのではないかと思います。

0
lesleyb