年と売り上げを持つテーブルがある。
select * from sales;
+------+------+
| year | sale |
+------+------+
| 1990 | 50 |
| 1991 | 51 |
| 1992 | 52 |
| 1993 | 52 |
| 1994 | 50 |
| 1995 | 50 |
| 1996 | 49 |
| 1997 | 55 |
+------+------+
前年度の売り上げと比較し、結果に応じた出力を行う。
select
s1.year
,s1.sale
,case
when sale =
(
select
sale
from
sales s2
where
s2.year = s1.year -1
) then '→'
when sale >
(
select
sale
from
sales s2
where
s2.year = s1.year -1
) then '↑'
when sale <
(
select
sale
from
sales s2
where
s2.year = s1.year -1
) then '↓'
else '-' end as var
from
sales s1
order by year;
+------+------+-----+
| year | sale | var |
+------+------+-----+
| 1990 | 50 | - |
| 1991 | 51 | ↑ |
| 1992 | 52 | ↑ |
| 1993 | 52 | → |
| 1994 | 50 | ↓ |
| 1995 | 50 | → |
| 1996 | 49 | ↓ |
| 1997 | 55 | ↑ |
+------+------+-----+
相関サブクエリの結合条件で-1とすることで
前年度のレコードを比較対象としている。
次は時系列に歯抜けがある場合
select * from sales2;
+------+------+
| year | sale |
+------+------+
| 1990 | 50 |
| 1992 | 50 |
| 1993 | 52 |
| 1994 | 55 |
| 1997 | 55 |
+------+------+
select
s1.year
,s1.sale
,case
when sale = (
select
sale
from
sales2 s2
where
year = (
select
max(year)
from
sales s3
where
s1.year > s3.year
)
) then '→'
when sale > (
select
sale
from
sales2 s2
where
year = (
select
max(year)
from
sales s3
where
s1.year > s3.year
)
) then '↑'
when sale < (
select
sale
from
sales2 s2
where
year = (
select
max(year)
from
sales s3
where
s1.year > s3.year
)
) then '↓'
else '-' end as var
from
sales2 s1
+------+------+-----+
| year | sale | var |
+------+------+-----+
| 1990 | 50 | - |
| 1992 | 50 | - |
| 1993 | 52 | ↑ |
| 1994 | 55 | ↑ |
| 1997 | 55 | - |
+------+------+-----+
上記2つのSQLでは3回サブクエリを実行しているが、
1つにまとめられるようだ。
SELECT
S1.year
,S1.sale
,CASE SIGN(sale - (
SELECT sale
FROM Sales S2
WHERE S2.year = S1.year - 1)
)
WHEN 0 THEN '→' /* 横ばい */
WHEN 1 THEN '↑' /* 成長 */
WHEN -1 THEN '↓' /* 後退 */
ELSE '-' END AS var
FROM Sales S1
ORDER BY year;
こちらを参考にさせていただきました。
達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ