本エントリはMySQL Casual Advent Calendar の9日目です。
MySQL Lab坂の8.0 (Optimizer)では、CTEが実装されています。詳しくは次のエントリをどうぞ。
MySQL 8.0 Lab版: MySQLの (再帰)共通テーブル式(CTE)
まあじっくり攻めるなら上記エントリでいいのですが、ここは簡単にざっくり動かしてみます。
まずlab坂の当該パッケージはRHEL7のtarballとソースしか配布されていません。
このtarballをCentOS7のmysql sandboxで動かします。
解凍して8.0.0にディレクトリ名を8.0.0とすると動きませんので、まぁ一番近い5.7の、
まぁ使わないバージョンとして5.7.1としてインストールして、make_sandbox 5.7.1とします。
ユーザテーブルがうまく作成されないみたいなので、my.sandbox.cnfを以下のようにします。
[client]
#user = msandbox
user = root
#password = msandbox
./start
./use
で起動、ログイン可能です。データベースtestをつくり、
create database test;
ここ十年くらい使っている以下のサンプルを作成します。
階層構造を隣接リストで表現
こんな感じで、テーブル、データをつくり、
use test;
CREATE TABLE shain(empid INT PRIMARY KEY, name VARCHAR(20), mgrid INTEGER) charset=utf8;
INSERT INTO shain VALUES ( 1, 'みやはら', NULL);
INSERT INTO shain VALUES ( 2, 'きむら', 1);
INSERT INTO shain VALUES ( 3, 'かまたき', 1);
INSERT INTO shain VALUES ( 4, '加藤', 2);
INSERT INTO shain VALUES ( 5, '林', 2);
INSERT INTO shain VALUES ( 6, '三浦', 5);
以下のクエリを実行します。
mysql > WITH RECURSIVE n AS
-> (
-> SELECT empid, name FROM shain WHERE name = 'きむら'
-> UNION ALL
-> SELECT nnext.empid, nnext.name FROM shain as nnext, n WHERE n.empid= nnext.mgrid
-> )
-> SELECT * FROM n;
+-------+-----------+
| empid | name |
+-------+-----------+
| 2 | きむら |
| 4 | 加藤 |
| 5 | 林 |
| 6 | 三浦 |
+-------+-----------+
4 rows in set (0.00 sec)
キモは上記のように初期集合を求めるSELECTと再帰集合を求めるSELECTをUNION ALLし、
それに共通表名をつけ、SELECTするところです。
WITH RECURSIVE 共通表名 AS
(
初期集合を求めるSELECT
UNION ALL
再帰集合を求めるSELECT
)
SELECT * FROM 共通表名
ではでは。
MySQL Lab坂の8.0 (Optimizer)では、CTEが実装されています。詳しくは次のエントリをどうぞ。
MySQL 8.0 Lab版: MySQLの (再帰)共通テーブル式(CTE)
まあじっくり攻めるなら上記エントリでいいのですが、ここは簡単にざっくり動かしてみます。
まずlab坂の当該パッケージはRHEL7のtarballとソースしか配布されていません。
このtarballをCentOS7のmysql sandboxで動かします。
解凍して8.0.0にディレクトリ名を8.0.0とすると動きませんので、まぁ一番近い5.7の、
まぁ使わないバージョンとして5.7.1としてインストールして、make_sandbox 5.7.1とします。
ユーザテーブルがうまく作成されないみたいなので、my.sandbox.cnfを以下のようにします。
[client]
#user = msandbox
user = root
#password = msandbox
./start
./use
で起動、ログイン可能です。データベースtestをつくり、
create database test;
ここ十年くらい使っている以下のサンプルを作成します。
階層構造を隣接リストで表現
こんな感じで、テーブル、データをつくり、
use test;
CREATE TABLE shain(empid INT PRIMARY KEY, name VARCHAR(20), mgrid INTEGER) charset=utf8;
INSERT INTO shain VALUES ( 1, 'みやはら', NULL);
INSERT INTO shain VALUES ( 2, 'きむら', 1);
INSERT INTO shain VALUES ( 3, 'かまたき', 1);
INSERT INTO shain VALUES ( 4, '加藤', 2);
INSERT INTO shain VALUES ( 5, '林', 2);
INSERT INTO shain VALUES ( 6, '三浦', 5);
以下のクエリを実行します。
mysql > WITH RECURSIVE n AS
-> (
-> SELECT empid, name FROM shain WHERE name = 'きむら'
-> UNION ALL
-> SELECT nnext.empid, nnext.name FROM shain as nnext, n WHERE n.empid= nnext.mgrid
-> )
-> SELECT * FROM n;
+-------+-----------+
| empid | name |
+-------+-----------+
| 2 | きむら |
| 4 | 加藤 |
| 5 | 林 |
| 6 | 三浦 |
+-------+-----------+
4 rows in set (0.00 sec)
キモは上記のように初期集合を求めるSELECTと再帰集合を求めるSELECTをUNION ALLし、
それに共通表名をつけ、SELECTするところです。
WITH RECURSIVE 共通表名 AS
(
初期集合を求めるSELECT
UNION ALL
再帰集合を求めるSELECT
)
SELECT * FROM 共通表名
ではでは。