Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Mysql sortowanie danych hierarchicznych

Studiowałem http://explainextended.com/2009/03 /17/hierarchiczne-zapytania-w-mysql/ i znalazłeś rozwiązanie Twojego problemu. Myślę, że masz już swoje rozwiązanie, ale dla każdego innego, kto szuka tego samego rozwiązania, odpowiadam tutaj.

Moje rozwiązanie sprawdzi się również w przypadku tabel relacyjnych, ponieważ nie możemy ustawić zero (0) w polu nadrzędnym w tabeli relacyjnej. Będzie to NULL, a moje rozwiązanie działa idealnie również w przypadku tabel relacyjnych.

Funkcja

DROP FUNCTION IF EXISTS hierarchy_connect_by_parent_eq_prior_id;
DELIMITER $$
CREATE FUNCTION hierarchy_connect_by_parent_eq_prior_id(value INT) RETURNS INTEGER
NOT DETERMINISTIC
READS SQL DATA
BEGIN
    DECLARE _parent INT;
    DECLARE _rank INT;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL;

    SET _parent = @id;
    SET _rank = 0;

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

    LOOP
        SET @innerrank = 0;
        SELECT p.id 
        INTO   @id
        FROM   (
                SELECT   id, @innerrank := @innerrank+1 AS rank 
                FROM     yourTable 
                WHERE    COALESCE(parent, 0) = _parent 
                ORDER BY yourField
                ) p 
        WHERE   p.rank > _rank LIMIT 0, 1;
        IF @id IS NOT NULL OR _parent = @start_with THEN
                SET @level = @level + 1;
                RETURN @id;
        END IF;
        SET @level := @level - 1;
        SET @innerrank = 0;
        SELECT COALESCE(p.parent, 0), p.rank
        INTO   _parent, _rank
        FROM   (
                SELECT id, parent, @innerrank := @innerrank+1 AS rank
                FROM    yourTable
                WHERE   COALESCE(parent, 0) = (
                    SELECT COALESCE(parent, 0) FROM yourTable WHERE id = _parent
                    ) 
                ORDER BY yourField
               ) p
        WHERE p.id = _parent;
    END LOOP;       
END;
$$
DELIMITER ;

Zastąp yourTable z nazwą Twojej tabeli i yourField z nazwą pola, według którego chcesz sortować dane.

Zapytanie

SELECT ou.* FROM (
    SELECT hi.id, parent, yourField 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, yourTable 
            WHERE @id IS NOT NULL
        ) ho 
    JOIN yourTable hi ON hi.id = ho.id
) ou

Zastąp yourTable z nazwą Twojej tabeli i yourField z nazwą pola, które chcesz wyświetlić.

Spowoduje to uzyskanie pożądanego rezultatu. Przetestowałem to i działa dobrze.

Oto http://sqlfiddle.com/#!9/9d060d/2 aby zobaczyć to w akcji.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak oddzielić rekord, aby uzyskać kwotę

  2. Dołącz do wielu stołów, zachowując NULL

  3. Jak używać funkcji Rand w połączeniu z Union w MySQL?

  4. Jak połączyć lokalnie hostowaną bazę danych MySQL z kontenerem docker?

  5. Czy EXISTS jest bardziej wydajne niż COUNT(*)>0?