テーブル構成としては②で良くて、親IDを利用した自己結合が必要になってくるはずです。
何段階でも返信ができるようにするのであれば、WITH RECURSIVE
をつかった結合を利用すると
一度にデータを抽出できます。
ただSQLとしてはちょっとややこしくなるので、返信できる深さの上限を決めて複数回のSELECTを行う、でも良いとは思います。
テーブルの例
sql
1CREATE TABLE messages (
2 id INT AUTO_INCREMENT PRIMARY KEY,
3 parent_id INT NULL,
4 content TEXT,
5 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
6 FOREIGN KEY (parent_id) REFERENCES messages(id)
7);
8
9INSERT INTO messages (id, parent_id, content) VALUES (1, NULL, 'これは親メッセージです');
10INSERT INTO messages (id, parent_id, content) VALUES (2, 1, 'これは親メッセージへの返信です');
11INSERT INTO messages (id, parent_id, content) VALUES (3, 1, '親メッセージへの別の返信です');
12INSERT INTO messages (id, parent_id, content) VALUES (4, 2, 'これは最初の返信への返信です');
13INSERT INTO messages (id, parent_id, content) VALUES (5, NULL, 'これは別の親メッセージです');
14INSERT INTO messages (id, parent_id, content) VALUES (6, 5, '2つ目の親メッセージへの返信です');
15INSERT INTO messages (id, parent_id, content) VALUES (7, 6, '2つ目の親メッセージの返信への返信です');
SELECTの例
sql
1WITH RECURSIVE threads AS (
2 SELECT
3 id,
4 parent_id,
5 content,
6 created_at,
7 id AS top_id,
8 CAST(id AS CHAR(255)) AS path,
9 0 AS depth
10 FROM messages
11 WHERE parent_id IS NULL
12
13 UNION ALL
14 SELECT
15 m.id,
16 m.parent_id,
17 m.content,
18 m.created_at,
19 t.top_id,
20 CONCAT(t.path, '-', m.id) AS path,
21 t.depth + 1 AS depth
22 FROM messages m
23 INNER JOIN threads t ON m.parent_id = t.id
24)
25SELECT * FROM threads
26ORDER BY top_id DESC, path
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2024/08/31 16:03