数値列のあるテーブルがあるとします(「スコア」と呼びます)。
カウントのテーブルを生成します。これは、各範囲にスコアが何回出現したかを示します。
例えば:
スコア範囲|発生回数 ------------------------------------- 0-9 | 11 10-19 | 14 20-29 | 3 ... | ...
この例では、0〜9の範囲のスコアを持つ11行と、10〜19の範囲のスコアを持つ14行と、20〜29の範囲のスコアを持つ3行がありました。
これを設定する簡単な方法はありますか?何がお勧めですか?
最も投票数の多い回答はどちらもSQLServer 2000では正しくありません。おそらく、異なるバージョンを使用していた可能性があります。
SQLServer 2000での両方の正しいバージョンを以下に示します。
select t.range as [score range], count(*) as [number of occurences]
from (
select case
when score between 0 and 9 then ' 0- 9'
when score between 10 and 19 then '10-19'
else '20-99' end as range
from scores) t
group by t.range
または
select t.range as [score range], count(*) as [number of occurences]
from (
select user_id,
case when score >= 0 and score< 10 then '0-9'
when score >= 10 and score< 20 then '10-19'
else '20-99' end as range
from scores) t
group by t.range
別のアプローチでは、クエリに範囲を埋め込む代わりに、テーブルに範囲を格納します。次のようなテーブルが作成され、Rangesと呼ばれます。
LowerLimit UpperLimit Range
0 9 '0-9'
10 19 '10-19'
20 29 '20-29'
30 39 '30-39'
そして、次のようなクエリ:
Select
Range as [Score Range],
Count(*) as [Number of Occurences]
from
Ranges r inner join Scores s on s.Score between r.LowerLimit and r.UpperLimit
group by Range
これは、テーブルを設定することを意味しますが、目的の範囲が変わったときに簡単に維持できます。コードを変更する必要はありません!
ここには、SQL Serverの構文では機能しない回答があります。私は使うだろう:
select t.range as [score range], count(*) as [number of occurences]
from (
select case
when score between 0 and 9 then ' 0-9 '
when score between 10 and 19 then '10-19'
when score between 20 and 29 then '20-29'
...
else '90-99' end as range
from scores) t
group by t.range
編集:コメントを見る
Postgresの場合(||
は文字列連結演算子です):
select (score/10)*10 || '-' || (score/10)*10+9 as scorerange, count(*)
from scores
group by score/10
order by 1
与える:
scorerange | count
------------+-------
0-9 | 11
10-19 | 14
20-29 | 3
30-39 | 2
ジェームス・カランの答えは私の意見では最も簡潔でしたが、出力は正しくありませんでした。 SQL Serverの場合、最も単純なステートメントは次のとおりです。
SELECT
[score range] = CAST((Score/10)*10 AS VARCHAR) + ' - ' + CAST((Score/10)*10+9 AS VARCHAR),
[number of occurrences] = COUNT(*)
FROM #Scores
GROUP BY Score/10
ORDER BY Score/10
これは、テストに使用した#Scores一時テーブルを想定しており、0から99の間の乱数で100行を挿入しました。
create table scores (
user_id int,
score int
)
select t.range as [score range], count(*) as [number of occurences]
from (
select user_id,
case when score >= 0 and score < 10 then '0-9'
case when score >= 10 and score < 20 then '10-19'
...
else '90-99' as range
from scores) t
group by t.range
select cast(score/10 as varchar) + '-' + cast(score/10+9 as varchar),
count(*)
from scores
group by score/10
これにより、範囲を指定する必要がなくなり、SQLサーバーに依存しなくなります。数学FTW!
SELECT CONCAT(range,'-',range+9), COUNT(range)
FROM (
SELECT
score - (score % 10) as range
FROM scores
)
すべてのケースを定義する必要なくスケーリングできるように、これを少し異なる方法で行います。
select t.range as [score range], count(*) as [number of occurences]
from (
select FLOOR(score/10) as range
from scores) t
group by t.range
テストされていないが、あなたはアイデアを得る...
declare @RangeWidth int
set @RangeWidth = 10
select
Floor(Score/@RangeWidth) as LowerBound,
Floor(Score/@RangeWidth)+@RangeWidth as UpperBound,
Count(*)
From
ScoreTable
group by
Floor(Score/@RangeWidth)
(Range
)でソートされる列はストリングであるため、数値ソートの代わりにストリング/ワードソートが使用されます。
文字列に数字の長さを埋めるためのゼロがある限り、ソートは意味的に正しいはずです:
SELECT t.range AS ScoreRange,
COUNT(*) AS NumberOfOccurrences
FROM (SELECT CASE
WHEN score BETWEEN 0 AND 9 THEN '00-09'
WHEN score BETWEEN 10 AND 19 THEN '10-19'
ELSE '20-99'
END AS Range
FROM Scores) t
GROUP BY t.Range
範囲が混在している場合は、追加のゼロを追加するだけです:
SELECT t.range AS ScoreRange,
COUNT(*) AS NumberOfOccurrences
FROM (SELECT CASE
WHEN score BETWEEN 0 AND 9 THEN '000-009'
WHEN score BETWEEN 10 AND 19 THEN '010-019'
WHEN score BETWEEN 20 AND 99 THEN '020-099'
ELSE '100-999'
END AS Range
FROM Scores) t
GROUP BY t.Range
試して
SELECT (str(range) + "-" + str(range + 9) ) AS [Score range], COUNT(score) AS [number of occurances]
FROM (SELECT score, int(score / 10 ) * 10 AS range FROM scoredata )
GROUP BY range;
select t.blah as [score range], count(*) as [number of occurences]
from (
select case
when score between 0 and 9 then ' 0-9 '
when score between 10 and 19 then '10-19'
when score between 20 and 29 then '20-29'
...
else '90-99' end as blah
from scores) t
group by t.blah
MySQLを使用している場合は、「範囲」以外のWordを使用するようにしてください。使用しない場合、上記の例を実行するとエラーが発生します。