Kawałek Kodu

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ć?