簡體   English   中英

MySQL:選擇行和所有相關行

[英]MySQL: Select row and all related rows

我有一個categories表設置,如:

ID    CatName      CatParent
1     Websites     NULL
2     Recipes      NULL
3     Programming  1
4     Helpful      3
5     Useless      3
6     Desserts     2

如果我有類別ID,我想查詢數據庫,按祖先的順序選擇類別和所有父項。 每個類別都有一個CatParent ,它是父級,如果沒有父級,則為NULL

因此,例如,如果我的類別ID為4,我想要一個返回的查詢:

array('4','3','1'); // Helpful > Programming > Websites

或者,如果我的類別ID為6:

array('6','2'); // Desserts > Recipes

或者類別ID為1:

array('1');

我該如何構建此查詢?

您可以使用left join來獲取父類別,但這只有在有限制時才有意義。 對於無限的類別深度,我會用PHP做。 不過,這是一個示例查詢:

select c1.id, c2.id, c3.id
from categories c1 
left join categories c2 on c2.id = c1.catparent
left join categories c3 on c3.id = c2.catparent
where c1.id = 4

如果類別4只有一個父級,則最后一個ID(c3.id)將為NULL。 您必須在代碼中考慮這一點。

為此,您可以創建一個過程。 如果使用phpmyadmin,您可以轉到數據庫,轉到SQL並插入以下內容:

DELIMITER //
CREATE PROCEDURE get_parents(IN cid int)
BEGIN
    DECLARE child_id int DEFAULT 0;
    DECLARE prev_id int DEFAULT cid;
    DECLARE loopran int DEFAULT 0; 

    SELECT CatParent into child_id 
    FROM categories WHERE ID=cid ;

    create TEMPORARY  table IF NOT EXISTS temp_table as (select * from categories where 1=0);
    truncate table temp_table;

    WHILE child_id <> 0 OR loopran <> 1 DO
        SET loopran = 1;

        insert into temp_table select * from categories WHERE ID=prev_id;
        SET prev_id = child_id;
        SET child_id=0;
        SELECT CatParent into child_id
        FROM categories WHERE ID=prev_id;
    END WHILE;

    select * from temp_table;
END //

該過程創建一個臨時表來存儲數據。 變量loopran,只是為了確保即使類別沒有子節點,也會返回父節點作為結果。

接下來,檢索結果:

$id = 5;

$result = "
CALL get_parents($id)
"; // Call the procedure just like as if it were a php function

$query = mysqli_query($conn, $result) or die(mysqli_error($conn));

$x = 0;

while ($row = mysqli_fetch_array($query)) {
    if ($x > 0) echo ", ";
    echo $row['ID'] . " | " . $row['CatParent'];
    $x++;
}

$id = 4返回: 4 | 3, 3 | 1 4 | 3, 3 | 1

$id = 6返回: 6 | 2 6 | 2

$id = 1返回: 1 |

$id = 9什么都不返回(如果該行不存在,當然。)

有一個很大的問題。 也就是說,如果你最終進入一個循環,最終指向循環中的前一個id,它將導致無限循環。 要解決此問題,您必須退出while循環,條件是它嘗試添加已添加的內容。 但我認為這絕不會自然而然地發生。 (當然,取決於你使用它的方式,以及如何設置ParentID)

來源和信用:@Meherzad - https://stackoverflow.com/a/16514403/2506641

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM