it-swarm.com.de

Wie kann man in SQL in Bereichen "gruppieren"?

Angenommen, ich habe eine Tabelle mit einer numerischen Spalte (nennen wir es "Punktzahl").

Ich möchte eine Zählungstabelle erstellen, aus der hervorgeht, wie oft die Ergebnisse in den einzelnen Bereichen angezeigt wurden.

Beispielsweise:

 Spielstand | Anzahl der Vorkommen 
 --------------------------------- 
 0-9 | 11 
 10-19 | 14 
 20-29 | 3 
 ... | ... 

In diesem Beispiel gab es 11 Zeilen mit Bewertungen im Bereich von 0 bis 9, 14 Zeilen mit Bewertungen im Bereich von 10 bis 19 und 3 Zeilen mit Bewertungen im Bereich von 20 bis 29.

Gibt es eine einfache Möglichkeit, dies einzurichten? Was empfehlen Sie?

168
Hugh

Keine der Antworten mit der höchsten Bewertung ist in SQL Server 2000 korrekt. Möglicherweise wurde eine andere Version verwendet.

Hier sind die richtigen Versionen von beiden auf SQL Server 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

oder

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
132
Ron Tuffin

Ein alternativer Ansatz besteht darin, die Bereiche in einer Tabelle zu speichern, anstatt sie in die Abfrage einzubetten. Am Ende haben Sie eine Tabelle, die Sie Ranges nennen und so aussieht:

LowerLimit   UpperLimit   Range 
0              9          '0-9'
10            19          '10-19'
20            29          '20-29'
30            39          '30-39'

Und eine Abfrage, die so aussieht:

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

Dies bedeutet zwar, eine Tabelle einzurichten, es ist jedoch einfach zu pflegen, wenn sich die gewünschten Bereiche ändern. Keine Codeänderungen notwendig!

32
Walter Mitty

Ich sehe hier Antworten, die in der SQL Server-Syntax nicht funktionieren. Ich würde ... benutzen:

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

BEARBEITEN: siehe Kommentare

30
Ken Paul

In postgres (wo || ist der String-Verkettungsoperator):

select (score/10)*10 || '-' || (score/10)*10+9 as scorerange, count(*)
from scores
group by score/10
order by 1

gibt:

 scorerange | count 
------------+-------
 0-9        |    11
 10-19      |    14
 20-29      |     3
 30-39      |     2
21
mhawke

James Currans Antwort war meiner Meinung nach die prägnanteste, aber die Ausgabe war nicht korrekt. Für SQL Server lautet die einfachste Anweisung wie folgt:

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

Dies setzt eine temporäre Tabelle #Scores voraus, die ich zum Testen verwendet habe. Ich habe gerade 100 Zeilen mit einer Zufallszahl zwischen 0 und 99 gefüllt.

10
Timothy Walters
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
5
tvanfosson
select cast(score/10 as varchar) + '-' + cast(score/10+9 as varchar), 
       count(*)
from scores
group by score/10
5
James Curran

Auf diese Weise müssen Sie keine Bereiche angeben und müssen SQL Server-unabhängig sein. Mathe FTW!

SELECT CONCAT(range,'-',range+9), COUNT(range)
FROM (
  SELECT 
    score - (score % 10) as range
  FROM scores
)
4
trevorgrayson

Ich würde das etwas anders machen, damit es skaliert, ohne jeden Fall definieren zu müssen:

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

Nicht getestet, aber Sie haben die Idee ...

3
JoshNaro
declare @RangeWidth int

set @RangeWidth = 10

select
   Floor(Score/@RangeWidth) as LowerBound,
   Floor(Score/@RangeWidth)[email protected] as UpperBound,
   Count(*)
From
   ScoreTable
group by
   Floor(Score/@RangeWidth)
2
Aheho

Da es sich bei der Spalte, nach der sortiert wird (Range), um eine Zeichenfolge handelt, wird die Zeichenfolge-/Wortsortierung anstelle der numerischen Sortierung verwendet.

Solange die Zeichenfolgen Nullen haben, um die Zahlenlängen aufzufüllen, sollte die Sortierung noch semantisch korrekt sein:

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

Wenn der Bereich gemischt ist, füllen Sie einfach eine zusätzliche Null auf:

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
1
Kevin Hogg

Versuchen

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;
1
Stubo
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

Stellen Sie sicher, dass Sie ein anderes Wort als "range" verwenden, wenn Sie sich in MySQL befinden. Andernfalls wird eine Fehlermeldung angezeigt, wenn Sie das obige Beispiel ausführen.

1
Danny Hui