販売データの実績を取るときのSQLで異なる期間のデータを比較したい時がありますよね。例えば本年の実績と前年の実績を取って前年比を出したいなど。
2回クエリを実行して画面上で計算させるのもいいですが、一回のクエリでとれた方が便利です。
そんな時はUNION ALLを使えば実現できます。
目次
サンプルコード
サンプルはこんな感じです。
select
sum(A.売上台数) as 売上台数,
sum(A.売上台数2) as 売上台数2,
(sum(A.売上台数)/sum(A.売上台数2))*100 as 前年比
from (
select
売上台数,
0 as 売上台数2
from
売上実績
where
年 = 2019
UNION ALL
select
0 as 売上台数,
売上台数 as 売上台数2
from
売上実績
where
年 = 2018
) as A
結果は以下のようになります。
売上台数 | 売上台数2 | 前年比 |
5000 | 6500 | 76.92 |
解説
まず、下記のような年をキーにした売上実績テーブルがあるとします。
・売上実績
年 | 売上台数 | 売上金額 |
2018 | 5000 | 1200000 |
2019 | 6500 | 1500000 |
単純に2018年の売上台数を取得したいときのSQLは以下のように書きます。
select 売上台数 from 売上実績 where 年 = 2018
結果は以下になります。
売上台数 |
5000 |
最初に記述した通りこのSQLを年を変更して2回実行して値を取って、画面上で計算させるものいいのですが、シンプルではありません。
そういう時はUNION ALLで2つのクエリをひとつにまとめてあげます。
--①2019年の実績 ここから-----------------
select
売上台数,
0 as 売上台数2 //架空の0
from
売上実績
where
年 = 2019
--①ここまで-------------------------------
UNION ALL
--②2018年の実績ここから--------------------
select
0 as 売上台数, //架空の0
売上台数 as 売上台数2
from
売上実績
where
年 = 2018
--②ここまで---------------------------------
結果は以下になります。UNION ALLを使うことでレコードを合体していくことができます。
売上台数 | 売上台数2 |
5000 | 0 |
0 | 6500 |
でもこのままではまだ使えないですよね。 架空の0も何なのか気になりますよね。
本当は下記のように1レコードで表示したいはずです。
売上台数 | 売上台数2 |
5000 | 6500 |
そこでこの合体したSQLをひとつのテーブルと見なして、もう一度データを取得するのです。
架空の0の項目を作り、売上台数と売上台数2をずらしてデータを取得することでsumを使って足し算してやります。
そうなると上記のように2つのレコードがひとつのレコードになります。
架空の0がないと下記のようになってsumを使って足し算しても全部足してしまいます。
売上台数 |
5000 |
6500 |
sumした結果↓↓ これでは今回の要件には合いません。
売上台数 |
11500 |
よって以下のように書くと上手くデータを取得できます。
--④Aテーブルからデータを取得 ここから-----------------
select
sum(A.売上台数) as 売上台数,
sum(A.売上台数2) as 売上台数2,
(sum(A.売上台数)/sum(A.売上台数2))*100 as 前年比
from (
--③UNIONした結果をひとつテーブルとする。(Aテーブル)
--①2019年の実績 ここから-----------------
select
売上台数,
0 as 売上台数2 //架空の0
from
売上実績
where
年 = 2019
--①ここまで-------------------------------
UNION ALL
--②2018年の実績ここから--------------------
select
0 as 売上台数, //架空の0
売上台数 as 売上台数2
from
売上実績
where
年 = 2018
--②ここまで---------------------------------
) as A
--③ここまで---------------------------------
--④ここまで---------------------------------
最後に
はい、以上がUNION ALLの活用方法です。あくまで活用事例なので他にもいい方法があるかもしれませんのでご了承ください。
それではまた!