Du bliver nødt til at bruge den lagrede procedure for at gøre det.
Find alle rækker med søgbar =1, gem deres id'er og forældre_id'er i en midlertidig tabel. Foretag derefter selv-joins for at tilføje forældre til denne midlertidige tabel. Gentag indtil der ikke kan tilføjes flere rækker (selvfølgelig skal du sørge for, at træet ikke er cyklisk). I slutningen har du kun en tabel med rækker, der har en søgbar efterkommer et sted nede i træet, så bare vis kun rækker uden forælder (øverst).
Hvis du antager, at din tabel hedder 'my_table', burde denne fungere:
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 ;
Så er det bare at kalde det:
CALL top_level_parents();
vil være lig medSELECT id FROM my_table WHERE id_is_top_level_and_has_searchable_descendant