Mysql / php id / parent_id modelini kullanarak bir kaydın tüm anne almak için en basit yolu nedir?

3 Cevap php

Ben ardışık komşuluk listesi / tek tablo devralma modeli kullanarak veritabanından tüm ana unsurları elde etmek için basit yol arıyorum (id, parent_id).

Benim seçme anda bu gibi görünüyor:

$sql = "SELECT
             e.id,
             TIME_FORMAT(e.start_time, '%H:%i') AS start_time,
             $title AS title,
             $description AS description,
             $type AS type,
             $place_name AS place_name,
             p.parent_id AS place_parent_id,
             p.city AS place_city,
             p.country AS place_country
         FROM event AS e
         LEFT JOIN place AS p ON p.id = e.place_id                          
         LEFT JOIN event_type AS et ON et.id = e.event_type_id
         WHERE e.day_id = '$day_id'
         AND e.private_flag = 0
         ORDER BY start_time";

Her event bir place bağlantılıdır ve her place başka place (kadar yaklaşık 5 düzeyleri derin) bir çocuk olabilir

Bu mysql ile tek bir select mümkün mü?

Şu anda ben bu iade $events dizi boyunca döngüler ayrı bir işlev olabilir düşünme gider gibi place_parent_X unsurlar ekleyerek, ama bunu uygulamak için nasıl emin değilim duyuyorum.

3 Cevap

Bu MySQL bunu yapmak mümkün, ama bir işlev oluşturmak ve bir sorguda kullanmak gerekir.

Ayrıntılı açıklamalar için bloguma bu girdiyi bakın:

İşte fonksiyonu ve sorgu şunlardır:

CREATE FUNCTION hierarchy_connect_by_parent_eq_prior_id(value INT) RETURNS INT
NOT DETERMINISTIC
READS SQL DATA
BEGIN
        DECLARE _id INT;
        DECLARE _parent INT;
        DECLARE _next INT;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL;

        SET _parent = @id;
        SET _id = -1;

        IF @id IS NULL THEN
                RETURN NULL;
        END IF;

        LOOP
                SELECT  MIN(id)
                INTO    @id
                FROM    place
                WHERE   parent = _parent
                        AND id > _id;
                IF @id IS NOT NULL OR _parent = @start_with THEN
                        SET @level = @level + 1;
                        RETURN @id;
                END IF;
                SET @level := @level - 1;
                SELECT  id, parent
                INTO    _id, _parent
                FROM    place
                WHERE   id = _parent;
        END LOOP;
END

SELECT  id, parent
FROM    (
        SELECT  hierarchy_connect_by_parent_eq_prior_id(id) AS id, @level AS level
        FROM    (
                SELECT  @start_with := 0,
                        @id := @start_with,
                        @level := 0
                ) vars, t_hierarchy
        WHERE   @id IS NOT NULL
        ) ho
JOIN    place hi
ON      hi.id = ho.id

İkincisi sorgu (Eğer @start_with değişkeni ayarlamak gerekir), belirli bir düğümün tüm alt seçecek

Belirli bir düğümün tüm atalarını bulmak için fonksiyonları olmadan basit bir sorgu kullanabilirsiniz:

SELECT  @r AS _id,
        @r := (
        SELECT  parent
        FROM    place
        WHERE   id = _id
        ) AS parent
FROM    (
        SELECT  @r := @node_id
        ) vars,
        place

Benim blog Bu makalede daha ayrıntılı olarak bu sorguyu anlattı:

Bu çözümleri hem makul bir süre çalışmak için, her iki id ve parent üzerine dizin olması gerekir.

Emin olun id bir PRIMARY KEY olarak tanımlanan ve bir seconday indeksine sahip olduğunu parent.

Bu standart ebeveyn-çocuk DB tasarımı ile mümkün değildir.

O noktaya ulaşmak için iş biraz alacak olsa Ancak, bir nested set yaklaşımı kullanmak ve bir sorguda bunu yapabilirdi.

Kolay nested sets gibi görünüyor.