SQLite3でグループ化した結果を更に絞り込んでみる

SQLite3で登録されている合計金額が◯円以上のユーザー名を調べたいとします。

使用するデータはパイソンでgimeiでSQLite3のRDB用のテストデータを用意してみるで作成したものを使います。

※ sample.sqlite3のパスが/path/to/dir/ledger.sqlite3で話を進めます。


# ledger.sqlite3があるディレクトリまで移動
$ cd /path/to/dir
$ sqlite3 ledger.sqlite3

始めに練習用の値を調べる為にクエリを実行してみます。

sqlite> SELECT user_id, SUM(amount) AS sum FROM ledger 
GROUP BY user_id 
ORDER BY sum DESC;
+---------+--------+
| user_id |  sum   |
+---------+--------+
| 94      | 576572 |
| 30      | 558279 |
| 98      | 551528 |
| 37      | 550874 |
| 44      | 549179 |
(途中省略)
+---------+--------+

今回のケースでは550000円以上のユーザー名を調べる事にします。

合計結果に対して絞り込みを行う場合はHAVING句を利用します。


HAVING句はWHERE句と挙動は似ていますが、GROUP BYでグループ化した結果に対して(今回であれば合算)、更に絞り込みを行いたい時にHAVING句で指定します。


上記内容を踏まえた上でHAVING句を含めたクエリを実行してみます。

sqlite> SELECT user_id, SUM(amount) AS sum FROM ledger 
GROUP BY user_id 
HAVING sum >= 550000 
ORDER BY sum DESC;
+---------+--------+
| user_id |  sum   |
+---------+--------+
| 94      | 576572 |
| 30      | 558279 |
| 98      | 551528 |
| 37      | 550874 |
+---------+--------+

HAVING句で絞り込みを行った事により、合算が550000円以上のユーザーを絞り込むことができました。


HAVING句を含めた一般構文は

SELECT カラム1, 集計関数(カラム2)
FROM テーブル名
WHERE 条件式 (グループ化前の絞り込み)
GROUP BY カラム1
HAVING 集計条件 (グループ化後の絞り込み)
ORDER BY カラム1;

になります。




最後に内部結合でユーザー名を取得してみます。

sqlite> SELECT users.id, users.name, SUM(ledger.amount) AS sum FROM ledger 
INNER JOIN users 
ON ledger.user_id = users.id 
GROUP BY user_id 
HAVING sum >>= 550000 
ORDER BY sum DESC;
+----+------+--------+
| id | name |  sum   |
+----+------+--------+
| 94 | 羽琉   | 576572 |
| 30 | 依奈   | 558279 |
| 98 | 妙奈   | 551528 |
| 37 | 典男   | 550874 |
+----+------+--------+

SQLite HAVING Clause with Practical Examples

京都の東本願寺で開催されているプログラミング教室で講師をしています。
詳しくはTera schoolを御覧ください。
マインクラフト用ビジュアルエディタを開発しています。

詳しくはinunosinsi/mcws_blockly - githubをご覧ください。