sql >> Database teknologi >  >> RDS >> Mysql

Hvordan vælger man underkategorier fra den valgte kategori ved hjælp af en indlejret funktion i PHP?

Der er et par løsninger. Først og fremmest vil jeg bruge følgende data (kategorier tabel) som et eksempel.

+----+--------------------------------+---------- +| id | navn | parent_id |+----+--------------------------------+----------+| 1 | Elektronik | NULL || 2 | Beklædning og tøj | NULL || 3 | Telefoner og tilbehør | 1 || 4 | Computer og kontor | 1 || 5 | Herretøj | 2 || 6 | Dametøj | 2 || 7 | Mobiltelefoner | 3 || 8 | Mobiltelefon tilbehør | 3 || 9 | Telefondele | 3 || 10 | Computere og tilbehør | 4 || 11 | Tabletter og tilbehør | 4 || 12 | Computerudstyr | 4 || 13 | Computerkomponenter | 4 || 14 | Kontorelektronik | 4 |+----+-----------------------------+--------+

Løsning 1 (Adjacency List ):

Du kan nemt hente enten alle kategorier eller underkategorier af en kategori i en enkelt forespørgsel ved hjælp af Med (almindelige tabeludtryk) klausul (kræver MySQL 8.0):

// Databaseforbindelse$options =[ PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => falsk, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,];$pdo =ny PDO('mysql:host=localhost;dbname=', '', '', $options); 
funktion getCategories(PDO $db, $parentId =null){ $sql =$parentId ? 'MED RECURSIVE cte (id, name, parent_id) AS (SELECT id, name, parent_id FROM categories WHERE parent_id =? UNION ALLE VÆLG c.id, c.name, c.parent_id FRA kategorier c INNER JOIN cte ON c.parent_id =cte.id) SELECT * FROM cte' :'SELECT * FROM kategorier'; $stmt =$db->prepare($sql); $stmt->execute($parentId? [$parentId]:null); returner $stmt->fetchAll();} 

Hvis du bruger MySQL 5.7, skal du ændre denne funktion sådan:

funktion getCategories(PDO $db, $parentId =null){ $sql =$parentId ? 'SELECT id, name, parent_id FROM (SELECT * FROM categories ORDER BY parent_id, id) c, (vælg @pv :=?) initialisering WHERE find_in_set(parent_id, @pv) AND LENGTH(@pv :=concat(@pv, ",", id))' :'VÆLG * FRA kategorier'; $stmt =$db->prepare($sql); $stmt->execute($parentId? [$parentId]:null); returner $stmt->fetchAll();} 

For at få alle kategorier i din database:

$allCategories =getCategories($pdo); 

Output:

+----+--------------------------------+---------- +| id | navn | parent_id |+----+--------------------------------+----------+| 1 | Elektronik | NULL || 2 | Beklædning og tøj | NULL || 3 | Telefoner og tilbehør | 1 || 4 | Computer og kontor | 1 || 5 | Herretøj | 2 || 6 | Dametøj | 2 || 7 | Mobiltelefoner | 3 || 8 | Mobiltelefontilbehør | 3 || 9 | Telefondele | 3 || 10 | Computere og tilbehør | 4 || 11 | Tabletter og tilbehør | 4 || 12 | Computerudstyr | 4 || 13 | Computerkomponenter | 4 || 14 | Kontorelektronik | 4 |+----+-----------------------------+--------+

Sådan får du underkategorier til en kategori:

$subCategories =getCategories($pdo, 1); // 1 er parent_id 

Output:

+----+--------------------------------+---------- +| id | navn | parent_id |+----+--------------------------------+----------+| 3 | Telefoner og tilbehør | 1 || 4 | Computer og kontor | 1 || 7 | Mobiltelefoner | 3 || 8 | Mobiltelefontilbehør | 3 || 9 | Telefondele | 3 || 10 | Computere og tilbehør | 4 || 11 | Tabletter og tilbehør | 4 || 12 | Computerudstyr | 4 || 13 | Computerkomponenter | 4 || 14 | Kontorelektronik | 4 |+----+-----------------------------+--------+

Hvis du vil have et HTML-output, kan du gå gennem $allCategories / $subCategories (baseret på dit eksempel):

funktion prepareCategories(array $categories){ $result =[ 'all_categories' => [], 'parent_categories' => [] ]; foreach ($categories as $category) { $result['all_categories'][$category['id']] =$category; $result['parent_categories'][$category['parent_id']][] =$category['id']; } returner $result;}funktion buildCategories($categories, $parentId =null){ if (!isset($categories['parent_categories'][$parentId])) { return ''; } $html ='
'; returner $html;} 
echo buildCategories(prepareCategories($allCategories)); 

Output:

echo buildCategories(prepareCategories($subCategories), 1); 

Output:

Løsning 2 (Indlejrede sæt ):

Vi tilføjer yderligere kolonner til venstre og right til vores tabel og læg tal i den, som vil identificere de grupper, der tilhører forælderen. (Bemærk, at vi ikke bruger parent_id kolonne.)

+----+--------------------------------+---------- ---------------+| id | navn | forældre_id | venstre | højre |+----+----------------------------+-------------------- -----------+| 1 | Elektronik | NULL | 1 | 22 || 2 | Beklædning og tøj | NULL | 23 | 28 || 3 | Telefoner og tilbehør | 1 | 2 | 9 || 4 | Computer og kontor | 1 | 10 | 21 || 5 | Herretøj | 2 | 24 | 25 || 6 | Dametøj | 2 | 26 | 27 || 7 | Mobiltelefoner | 3 | 3 | 4 || 8 | Mobiltelefontilbehør | 3 | 5 | 6 || 9 | Telefondele | 3 | 7 | 8 || 10 | Computere og tilbehør | 4 | 11 | 12 || 11 | Tabletter og tilbehør | 4 | 13 | 14 || 12 | Computerudstyr | 4 | 15 | 16 || 13 | Computerkomponenter | 4 | 17 | 18 || 14 | Kontorelektronik | 4 | 19 | 20 |+----+----------------------------+-------- -----------+

Nu skal vi ændre vores funktion:

funktion getCategories(PDO $db, $parentId =null){ $sql =$parentId ? 'VÆLG børn.* FRA kategorier forælder INNER JOIN-kategorier børn PÅ parent.left  children.left WHERE parent.id =?' :'VÆLG * FRA kategorier'; $stmt =$db->prepare($sql); $stmt->execute($parentId? [$parentId]:null); returner $stmt->fetchAll();} 

For at få alle kategorier i din database:

$allCategories =getCategories($pdo); 

Output:

+----+--------------------------------+---------- ---------------+| id | navn | forældre_id | venstre | højre |+----+----------------------------+-------------------- -----------+| 1 | Elektronik | NULL | 1 | 22 || 2 | Beklædning og tøj | NULL | 23 | 28 || 3 | Telefoner og tilbehør | 1 | 2 | 9 || 4 | Computer og kontor | 1 | 10 | 21 || 5 | Herretøj | 2 | 24 | 25 || 6 | Dametøj | 2 | 26 | 27 || 7 | Mobiltelefoner | 3 | 3 | 4 || 8 | Mobiltelefontilbehør | 3 | 5 | 6 || 9 | Telefondele | 3 | 7 | 8 || 10 | Computere og tilbehør | 4 | 11 | 12 || 11 | Tabletter og tilbehør | 4 | 13 | 14 || 12 | Computerudstyr | 4 | 15 | 16 || 13 | Computerkomponenter | 4 | 17 | 18 || 14 | Kontorelektronik | 4 | 19 | 20 |+----+----------------------------+-------- -----------+

Sådan får du underkategorier til en kategori:

$subCategories =getCategories($pdo, 1); // 1 er parent_id 

Output:

+----+--------------------------------+---------- ---------------+| id | navn | forældre_id | venstre | højre |+----+----------------------------+-------------------- -----------+| 3 | Telefoner og tilbehør | 1 | 2 | 9 || 4 | Computer og kontor | 1 | 10 | 21 || 7 | Mobiltelefoner | 3 | 3 | 4 || 8 | Mobiltelefontilbehør | 3 | 5 | 6 || 9 | Telefondele | 3 | 7 | 8 || 10 | Computere og tilbehør | 4 | 11 | 12 || 11 | Tabletter og tilbehør | 4 | 13 | 14 || 12 | Computerudstyr | 4 | 15 | 16 || 13 | Computerkomponenter | 4 | 17 | 18 || 14 | Kontorelektronik | 4 | 19 | 20 |+----+----------------------------+-------- -----------+

Du kan gengive HTML som vist i Løsning 1 . Læs mere om opdatering og indsættelse af nye data i indlejret sætmodel.

Kilder og læsninger:




  1. PostgreSQL belastningsbalancering ved hjælp af HAProxy &Keepalved

  2. Mysql2::Fejl:Forkert strengværdi

  3. SQL Server, konvertere en navngiven instans til standardinstans?

  4. BIN_TO_NUM() Funktion i Oracle