2014-06-10 109 views
1

我在这个问题上停留了一段时间。递归查询SQL Server

我有一个表称为范畴,看起来像这样:

number, name, parent 
1  , Fruit, null 
2  , Apples, 1 
3  , Golden Apples, 2 
4  , Pineapples, 1 

现在,我该如何选择主类别和其子类别和如果存在的话,它们的子类。

我必须在PHP输出这样的:

<div>Fruit 
    <div>Apples 
      <div>Golden Apples</div> 
    </div> 
    <div>Pineapples</div> 
</div> 

在理论上没有已知的结束或子类别的数量,你可以有。我一直在努力解决这个问题。

可以用循环完成此操作,然后运行查询以再次选择其子类别,但这在数据库端会非常耗费资源。

我希望有人能帮助我这个。

+0

你应该看看这里:http://technet.microsoft.com/en-us/library/ms186243%28v=sql.105%29.aspx – PeterRing

回答

0

理想的方法是规范化您的数据。有一个类别表和一个表,其中包含每个类别的成员。然后,您可以在表格之间进行简单的左连接,以获得您要查找的内容。既然你没有这些,你将需要从主表中选择,然后使用别名在同一个表上进行左连接。

这样的事情会起作用。

选择号码,从类别名称,其中母公司为NULL 左连接类别为Items上Items.Parent = Category.number

0

尝试使用递归CTE这样的:

--this is just an old example I've used before, but it kind of matches your table 
--go through a nested table supervisor - user table and display the chain 
DECLARE @Contacts table (id int, first_name varchar(10), reports_to_id int) 
INSERT @Contacts VALUES (1,'Jerome', NULL) -- tree is as follows: 
INSERT @Contacts VALUES (2,'Joe' ,'1')  --      1-Jerome 
INSERT @Contacts VALUES (3,'Paul' ,'2')  --     /  \ 
INSERT @Contacts VALUES (4,'Jack' ,'3')  --    2-Joe   9-Bill 
INSERT @Contacts VALUES (5,'Daniel','3')  --   /  \    \ 
INSERT @Contacts VALUES (6,'David' ,'2')  --  3-Paul   6-David  10-Sam 
INSERT @Contacts VALUES (7,'Ian' ,'6')  -- / \   / \ 
INSERT @Contacts VALUES (8,'Helen' ,'6')  -- 4-Jack 5-Daniel 7-Ian 8-Helen 
INSERT @Contacts VALUES (9,'Bill ' ,'1')  -- 
INSERT @Contacts VALUES (10,'Sam' ,'9')  -- 

DECLARE @Root_id int 

--get complete tree--------------------------------------------------- 
SET @Root_id=null 
PRINT '@Root_id='+COALESCE(''''+CONVERT(varchar(5),@Root_id)+'''','null') 
;WITH StaffTree AS 
(
    SELECT 
     c.id, c.first_name, c.reports_to_id, c.reports_to_id as Manager_id, cc.first_name AS Manager_first_name, 1 AS LevelOf 
     FROM @Contacts     c 
      LEFT OUTER JOIN @Contacts cc ON c.reports_to_id=cc.id 
     WHERE [email protected]_id OR (@Root_id IS NULL AND c.reports_to_id IS NULL) 
    UNION ALL 
     SELECT 
      s.id, s.first_name, s.reports_to_id, t.id, t.first_name, t.LevelOf+1 
     FROM StaffTree   t 
      INNER JOIN @Contacts s ON t.id=s.reports_to_id 
    WHERE [email protected]_id OR @Root_id IS NULL OR t.LevelOf>1 
) 
SELECT * FROM StaffTree ORDER BY LevelOf,first_name 

OUTPUT:

@Root_id=null 
     id first_name reports_to_id Manager_id Manager_first_name  LevelOf 
----------- ---------- ------------- ----------- ------------------ ----------- 
      1 Jerome    NULL  NULL NULL       1 
      9 Bill     1   1 Jerome      2 
      2 Joe     1   1 Jerome      2 
      6 David     2   2 Joe       3 
      3 Paul     2   2 Joe       3 
     10 Sam     9   9 Bill       3 
      5 Daniel     3   3 Paul       4 
      8 Helen     6   6 David      4 
      7 Ian     6   6 David      4 
      4 Jack     3   3 Paul       4 

(10 row(s) affected) 

我想你可以循环使用PHP中的结果集并构建你的DIV。