駆け出しエンジニアのNishです
今回はHaving句を利用して、特定条件を満たすグループの抽出についての記事です
事前準備
今回は、以下のデータを使用します
毎度のことながらダミーデータがテキトーですが、ご容赦。。
ec_saleテーブルには、各ユーザの購入履歴が保存されています
- 会員id(user_id)
- 任意で連携できる別サービスのid(member_id)
- 性別
- 購入した商品のカテゴリ
- 金額
上記の情報がこのテーブルに保存されているとします
member_idについては、別サービスの連携が任意なのでNullが入るのを許容しています
+---------+-----------+-----+---------------+------+
| user_id | member_id | sex | item_category | sale |
+---------+-----------+-----+---------------+------+
| 10001 | NULL | M | A | 3200 |
| 10002 | 779265 | M | B | 1200 |
| 10003 | 235340 | M | C | 5600 |
| 10004 | 34008 | W | B | 4200 |
| 10005 | NULL | W | B | 900 |
| 10006 | 193197 | M | A | 2000 |
| 10007 | 724526 | W | C | 1500 |
| 10008 | 85284 | M | A | 1000 |
| 10009 | 83226 | W | B | 2900 |
| 10010 | 30057 | W | C | 3000 |
+---------+-----------+-----+---------------+------+
10 rows in set (0.04 sec)
データ欠損を調べる
Having句を用いて、データ欠損があるかを調べます
ここで利用するのは、COUNT関数です
COUNT(*)はNULLも含めるのに対し、COUNT(<カラム名>)はNULLを除外することを利用します
別サービスを連携していないユーザが存在するかは次のクエリで確認できます
SELECT
'未登録ユーザ有' AS gap
FROM
ec_sale
HAVING
COUNT(*) <> COUNT(member_id)
Having句単体で利用して、テーブル全体を集約しています
要素数で条件を指定
特定条件を満たすレコード数を調べて、さらに絞り込みをかけたい場合の解説です
指定条件にマッチするレコード数を算出するには、以下のように書けばokなので、
SUM(CASE WHEN <指定条件> THEN 1 ELSE 0 END)
これをHaving句で使用します
例として、「女性より男性の方が購入している商品カテゴリー」を抽出するには、以下のクエリを実行します
SELECT
item_category
FROM
ec_sale
GROUP BY
item_category
HAVING
SUM(CASE WHEN sex = 'M' THEN 1 ELSE 0 END) > SUM(CASE WHEN sex = 'W' THEN 1 ELSE 0 END)
統計量で条件を指定
先ほどと同じように、Having句で集約関数を使用すればok
例として、「男性の平均購入価格が3000円以上の商品カテゴリー」を抽出するには、
以下のクエリを実行します
SELECT
item_category
FROM
ec_sale
GROUP BY
item_category
HAVING
AVG(CASE WHEN sex = 'M' THEN sale ELSE NULL END) > 3000