これを行うには、ストアドプロシージャを使用する必要があります。
searchable =1のすべての行を検索し、それらのIDとparent_idsを一時テーブルに格納します。次に、自己結合を実行して、この一時テーブルに親を追加します。行を追加できなくなるまで繰り返します(明らかに、ツリーが循環していないことを確認してください)。最後に、ツリーのどこかに検索可能な子孫がある行のみを含むテーブルがあるため、親のない行(上部)のみを表示します。
テーブルの名前が「my_table」であるとすると、これは機能するはずです:
DELIMITER //
DROP PROCEDURE IF EXISTS top_level_parents//
CREATE PROCEDURE top_level_parents()
BEGIN
DECLARE found INT(11) DEFAULT 1;
DROP TABLE IF EXISTS parent_tree;
CREATE TABLE parent_tree (id int(11) PRIMARY KEY, p_id int(11)) ENGINE=HEAP;
INSERT INTO parent_tree
SELECT id, parent_id FROM my_table
WHERE searchable = 1;
SET found = ROW_COUNT();
WHILE found > 0 DO
INSERT IGNORE INTO parent_tree
SELECT p.id, p.parent_id FROM parent_tree c JOIN my_table p
WHERE p.id = c.p_id;
SET found = ROW_COUNT();
END WHILE;
SELECT id FROM parent_tree WHERE p_id = 0;
DROP TABLE parent_tree;
END;//
DELIMITER ;
次に、それを呼び出すだけです:
CALL top_level_parents();
SELECT id FROM my_table WHERE id_is_top_level_and_has_searchable_descendant
と等しくなります