2016-12-10 73 views
4

我有一個categories表設置,如:MySQL的:選擇行和所有相關的行

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

如果我有一個類ID,我想查詢數據庫選擇類別和所有的父母,爲了的祖先。如果父母不存在,每個類別都有一個CatParent,它是父母,或NULL

因此,舉例來說,如果我有4個類別ID,我想返回的查詢:

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

或者,如果我有6個類別ID:

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

或者類別ID爲1:

array('1'); 

我該如何構建此查詢?

+0

是否有一個最大的類別深度?如果不是,只有一個查詢不能完成。 – Quagaar

+0

@Quagaar不,沒有最大分類深度,除非它被定義爲異常高的東西......比方說20。 – JROB

+0

你試過了一個循環嗎? (sql,而不是php) –

回答

2

您可以使用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。你必須在代碼中考慮這一點。

+0

感謝您發佈該信息,但我永遠無法獲得此結果。 – JROB

+0

連接的表名中有一個拼寫錯誤(catgories而不是類別)。但除此之外,查詢的作品。 – Quagaar

1

要實現這一點,您可以創建一個過程。如果使用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

$id = 6回報:6 | 2

$id = 1回報:1 |

$id = 9返回任何內容(如果該行做當然不存在。)

有一個巨大的問題。也就是說,如果你最終在一個循環中最終指向循環中的先前的id,它將導致無限循環。要解決這個問題,你必須退出while循環,條件是它試圖添加它已經添加的東西。但我認爲這絕不會自然發生。 (取決於你用什麼它,當然,和PARENTID如何設置)

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