Mamy tabelę z danymi, a jedna z cech danej (kolumna tabeli) jest wartością liczbową, którą chcemy przyporządkować do wybranego z ustalonych, nazwanych zakresów. W naszym przykładzie będzie to tabela temperatur.
temperatura |
---|
-23,5 |
-34,1 |
-36,6 |
-31,0 |
-26,8 |
17,0 |
-22,1 |
-5,7 |
-35,9 |
-34,5 |
34,0 |
39,1 |
5,0 |
6,4 |
-40,0 |
Przy małej ilości zakresów można to oczywiście osiągnąć poprzez konstrukcję CASE WHEN, np.:
SELECT t.temperatura,
CASE
WHEN t.temperatura>=-30 AND t.temperatura<-5 THEN 'mroźno'
WHEN t.temperatura>=-5 AND t.temperatura<0 THEN 'lekki mróz'
...
ELSE 'nie wiadomo' END
FROM temperatura AS t
Ale przy większej ilości zakresów będzie kłopot. Kłopot będzie również przy zmianie wartości lub opisów zakresów (ingerencja w zapytanie), albo przy wielojęzykowości serwisu gdzie opisy zakresów muszą być odpowiednie do języka.
Mróz, zimno, zimno...
Zakresy trzeba przenieść do tabeli i sprytnie połączyć je z tabelą wartości.
Niech nasza tabela zakresów wygląda tak:
zakres | od | do |
---|---|---|
bardzo mroźno | -1000 | -30 |
mroźno | -30 | -5 |
lekki mróz | -5 | 0 |
zimno | 0 | 5 |
chłodno | 5 | 15 |
letnio | 15 | 20 |
ciepło | 20 | 30 |
gorąco | 30 | 35 |
upał | 35 | 1000 |
Wtedy nasze zapytanie (już bez CASE WHEN) będzie wyglądać tak:
SELECT t.temperatura,zt.zakres
FROM temperatura AS t, zakres_temperatury AS zt
WHERE t.temperatura>=zt.od AND t.temperatura<zt.do
Ciepło, ciepło, gorąco!
Połączyliśmy tabelę temperatur (WHERE możesz przenieść do warunku JOIN) poprzez dwa warunki nierówności operujące na wartości temperatury oraz wartości "od" i "do" zakresu.
Należy pamiętać o tym, że jeśli koniec jednego zakresu jest taki sam jak początek kolejnego (w tabeli zakresów), to należy użyć nierówności ostrej (jak w przykładzie). Jeśli natomiast wartość "do" zakresu jest mniejsza od wartości "do" kolejnego, to obydwie nierówności mogą być nieostre. Zasada dotyczy również wartości "od".
A jak właściwie wygląda wynik?
temperatura | zakres |
---|---|
-23,5 | mroźno |
-34,1 | bardzo mroźno |
-36,6 | bardzo mroźno |
-31,0 | bardzo mroźno |
-26,8 | mroźno |
17,0 | letnio |
-22,1 | mroźno |
-5,7 | mroźno |
-35,9 | bardzo mroźno |
-34,5 | bardzo mroźno |
34,0 | gorąco |
39,1 | upał |
5,0 | chłodno |
6,4 | chłodno |
-40,0 | bardzo mroźno |
Nic nie stoi na przeszkodzie, aby w zapytaniu użyć grupowania i funkcji agregującej, np. aby policzyć ile rekordów wpada do danego przedziału.
SELECT COUNT(t.temperatura) AS ilosc,zt.zakres
FROM temperatura AS t, zakres_temperatury AS zt
WHERE t.temperatura>=zt.od AND t.temperatura<zt.do
GROUP BY zt.id_zakres /* ewentualnie GROUP BY zt.zakres */
Wiesz już jak się dziś ubrać?