2011-04-06 31 views
1

你能幫我寫下SQL select嗎?從「父母身份證」訂購的一張桌上選擇數據

我表:

地區

  • ID(INT)
  • 名(VARCHAR(50))
  • PARENT_ID(INT)

其中 「PARENT_ID」裁判到「身份證」。 parent_id設置爲0的行沒有父級,並且位於頂部。我需要選擇數據爲樹。

知道對不對即時通訊使用遞歸函數:)

function SelectData($parent=0, $padding='') 
{ 
$q = mysql_query("SELECT * FROM regions WHERE parent=$parent"); 
while($row = mysql_fetcharray($q)) 
{ 
    echo($row[name]); 
    priklad($row[id], $padding.'  '); 
} 
} 

我發現這是可能的CTE(Can I select full hierarchy of parents when id and parent id are in the same table?)做的,但也發現,MySQL不支持CTE。

那麼,有什麼辦法在MySQL中使用一個select而不是遞歸函數嗎? 謝謝:)

回答

0

您可以使用非遞歸MySQL的存儲過程,你可以從你的php調用如下:

調用示例如下

drop table if exists categories; 
create table categories 
(
cat_id smallint unsigned not null auto_increment primary key, 
name varchar(255) not null, 
parent_cat_id smallint unsigned null, 
key (parent_cat_id) 
) 
engine = innodb; 

insert into categories (name, parent_cat_id) values 
('Location',null), 
('Color',null), 
    ('USA',1), 
     ('Illinois',3), 
     ('Chicago',3), 
    ('Black',2), 
    ('Red',2); 


drop procedure if exists category_hier; 
delimiter # 

create procedure category_hier 
(
in p_cat_id smallint unsigned 
) 
begin 

declare v_done tinyint unsigned default 0; 
declare v_depth smallint unsigned default 0; 

create temporary table hier(
parent_cat_id smallint unsigned, 
cat_id smallint unsigned, 
depth smallint unsigned default 0 
)engine = memory; 

insert into hier select parent_cat_id, cat_id, v_depth from categories where cat_id = p_cat_id; 
create temporary table tmp engine=memory select * from hier; 

/* http://dev.mysql.com/doc/refman/5.0/en/temporary-table-problems.html */ 

while not v_done do 

    if exists(select 1 from categories c 
     inner join tmp on c.parent_cat_id = tmp.cat_id and tmp.depth = v_depth) then 

     insert into hier select c.parent_cat_id, c.cat_id, v_depth + 1 from categories c 
      inner join tmp on c.parent_cat_id = tmp.cat_id and tmp.depth = v_depth; 

     set v_depth = v_depth + 1;   

     truncate table tmp; 
     insert into tmp select * from hier where depth = v_depth; 

    else 
     set v_done = 1; 
    end if; 

end while; 

select 
c.cat_id, 
c.name as category_name, 
p.cat_id as parent_cat_id, 
p.name as parent_category_name, 
hier.depth 
from 
hier 
inner join categories c on hier.cat_id = c.cat_id 
left outer join categories p on hier.parent_cat_id = p.cat_id 
order by 
hier.depth; 

drop temporary table if exists hier; 
drop temporary table if exists tmp; 

end # 

delimiter ; 

call category_hier(1); 

call category_hier(2); 

$result = $conn->query(sprintf("call category_hier(%d)", $catID)); 

mysql> call category_hier(1); 
+--------+---------------+---------------+----------------------+-------+ 
| cat_id | category_name | parent_cat_id | parent_category_name | depth | 
+--------+---------------+---------------+----------------------+-------+ 
|  1 | Location  |   NULL | NULL     |  0 | 
|  3 | USA   |    1 | Location    |  1 | 
|  5 | Chicago  |    3 | USA     |  2 | 
|  4 | Illinois  |    3 | USA     |  2 | 
+--------+---------------+---------------+----------------------+-------+ 
4 rows in set (0.00 sec) 

mysql> call category_hier(2); 
+--------+---------------+---------------+----------------------+-------+ 
| cat_id | category_name | parent_cat_id | parent_category_name | depth | 
+--------+---------------+---------------+----------------------+-------+ 
|  2 | Color   |   NULL | NULL     |  0 | 
|  6 | Black   |    2 | Color    |  1 | 
|  7 | Red   |    2 | Color    |  1 | 
+--------+---------------+---------------+----------------------+-------+ 
3 rows in set (0.00 sec) 

全部腳本和測試數據

希望這有助於:)

0

step1->

select distinct ID from tbl where PARENT_ID=0 

存儲在數組中的值,然後對每個值的

步驟2->

select ID from TBL where PARENT_ID = $values_from_array 

或也許這將工作

select ID from TBL where PARENT_ID in (select distinct ID from tbl where PARENT_ID=0) order by PARENT_ID 
+0

那是什麼我的功能現在正在做的,但更深層。我的意思是,一個行可以有父,它可以有父,它可以有父,...... 我只是好奇,如果有辦法做到ID在一個查詢中選擇 – Buksy 2011-04-06 13:25:38

0

MyBB插件的一部分代碼。它的創建從hierarcical forums->子>子的組合框

function generate_video_category_select($name, $selectedId, $parent_id = 0, $depth = 1) 
     { 
      global $db; 
      $box = ''; 
      if($depth == 1) 
      { 
       $box .= '<select name="' . $name . '">'; 
       $box .='<option value="0" selected="selected">Boş</option>'; 
      } 


      $sql = "SELECT * FROM ".TABLE_PREFIX."aofvideo_categories WHERE parent_id = ".$parent_id." ORDER BY name ASC"; 

      $result = $db->query($sql); 
      while($row = $db->fetch_array($result)) 
      { 
       $box .='<option value="'.$row['id'].'"'.($selectedId == $row['id'] ? ' selected="selected"' : '').'>'.str_repeat('&nbsp;',$depth).$row['name'].'</option>'; 
       $box .= generate_video_category_select($name,$selectedId,$row['id'],$depth + 5); 
      } 

      if($depth == 1) 
       $box .="</select>"; 


      return $box; 
     } 
+0

是的,我在PHP similiar遞歸函數太多我很好奇,如果那裏有一個辦法做到這一點只在SQL沒有PHP – Buksy 2011-11-16 10:21:25

+0

,如果你使用的是Oracle的研究和他人,你可以搜索一下「由SP遞歸quering」「通過連接」。 – 2011-11-18 00:46:48

0

每當你需要從表依賴於其他信息在同一個表中提取信息,它是使用兩個「虛擬」是個好主意引用同一個表的表。在情況下,你知道,我們的關係只有兩種深,你可以使用下面的:

選擇a.name,b.name,從宗教,宗教b,其中a.id = b.parent_id

3一個例子是下列:

選擇a.name,b.name,從宗教c.name,宗教b,宗教c其中a.id = b.parent_id

希望有所幫助。