teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

回答を追記

2016/12/15 09:16

投稿

KiyoshiMotoki
KiyoshiMotoki

スコア4791

answer CHANGED
@@ -77,4 +77,81 @@
77
77
  連結リストは「再帰クエリ」(recursive query)と呼ぶ機能があると簡単に実現できますが、
78
78
  MySQL は再帰クエリを実装しておらず、ストアドプロシージャを使用する必要があるらしいからです。
79
79
  [https://en.wikipedia.org/wiki/Hierarchical_and_recursive_queries_in_SQL](https://en.wikipedia.org/wiki/Hierarchical_and_recursive_queries_in_SQL)
80
- > Though MySQL does not support common table expressions there exists a demonstration of WITH RECURSIVE emulation[17] using stored procedures.
80
+ > Though MySQL does not support common table expressions there exists a demonstration of WITH RECURSIVE emulation[17] using stored procedures.
81
+
82
+ # 以下追記
83
+
84
+ > 「obj」カラムと「sort」カラム、この2つを合わせてユニークキーになる
85
+
86
+ であれば、そのようにユニークインデックスを作成してやればよいです。
87
+ で、SELECT, UPDATE, INSERT する際にも obj カラムの値を指定してやれば、単一テーブルで実現できます。
88
+ ```sql
89
+ mysql> CREATE TABLE test (
90
+ -> id int PRIMARY KEY AUTO_INCREMENT,
91
+ -> text text,
92
+ -> created DATE,
93
+ -> obj int NOT NULL,
94
+ -> sort int NOT NULL,
95
+ -> UNIQUE KEY (obj, sort)
96
+ -> );
97
+ Query OK, 0 rows affected (0.04 sec)
98
+
99
+ mysql> INSERT INTO test (text, created, obj, sort) VALUES
100
+ -> ('こんにちは', '2016-12-11', 1, 1),
101
+ -> ('私の名前は太郎です', '2016-12-12', 1, 2),
102
+ -> ('どうぞよろしくお願いします。', '2016-12-13', 1, 3),
103
+ -> ('こんばんは', '2016-12-11', 2, 1),
104
+ -> ('私の名前は花子です', '2016-12-12', 2, 2),
105
+ -> ('どうぞよろしくお願いします。', '2016-12-13', 2, 3);
106
+ Query OK, 6 rows affected (0.01 sec)
107
+ Records: 6 Duplicates: 0 Warnings: 0
108
+
109
+ mysql> SELECT * FROM test ORDER BY obj, sort;
110
+ +----+--------------------------------------------+------------+-----+------+
111
+ | id | text | created | obj | sort |
112
+ +----+--------------------------------------------+------------+-----+------+
113
+ | 1 | こんにちは | 2016-12-11 | 1 | 1 |
114
+ | 2 | 私の名前は太郎です | 2016-12-12 | 1 | 2 |
115
+ | 3 | どうぞよろしくお願いします。 | 2016-12-13 | 1 | 3 |
116
+ | 4 | こんばんは | 2016-12-11 | 2 | 1 |
117
+ | 5 | 私の名前は花子です | 2016-12-12 | 2 | 2 |
118
+ | 6 | どうぞよろしくお願いします。 | 2016-12-13 | 2 | 3 |
119
+ +----+--------------------------------------------+------------+-----+------+
120
+ 6 rows in set (0.00 sec)
121
+
122
+ mysql> BEGIN;
123
+ Query OK, 0 rows affected (0.00 sec)
124
+
125
+ mysql> SELECT sort FROM test WHERE obj = 1 AND text = '私の名前は太郎です' FOR UPDATE;
126
+ +------+
127
+ | sort |
128
+ +------+
129
+ | 2 |
130
+ +------+
131
+ 1 row in set (0.01 sec)
132
+
133
+ mysql> UPDATE test SET sort = sort + 1 WHERE obj = 1 AND sort >= 2 ORDER BY sort DESC;
134
+ Query OK, 2 rows affected (0.02 sec)
135
+ Rows matched: 2 Changed: 2 Warnings: 0
136
+
137
+ mysql> INSERT INTO test (text, created, obj, sort) VALUES
138
+ -> ('はじめまして', '2016-12-13', 1, 2);
139
+ Query OK, 1 row affected (0.00 sec)
140
+
141
+ mysql> COMMIT;
142
+ Query OK, 0 rows affected (0.01 sec)
143
+
144
+ mysql> SELECT * FROM test ORDER BY obj, sort;
145
+ +----+--------------------------------------------+------------+-----+------+
146
+ | id | text | created | obj | sort |
147
+ +----+--------------------------------------------+------------+-----+------+
148
+ | 1 | こんにちは | 2016-12-11 | 1 | 1 |
149
+ | 7 | はじめまして | 2016-12-13 | 1 | 2 |
150
+ | 2 | 私の名前は太郎です | 2016-12-12 | 1 | 3 |
151
+ | 3 | どうぞよろしくお願いします。 | 2016-12-13 | 1 | 4 |
152
+ | 4 | こんばんは | 2016-12-11 | 2 | 1 |
153
+ | 5 | 私の名前は花子です | 2016-12-12 | 2 | 2 |
154
+ | 6 | どうぞよろしくお願いします。 | 2016-12-13 | 2 | 3 |
155
+ +----+--------------------------------------------+------------+-----+------+
156
+ 7 rows in set (0.00 sec)
157
+ ```