2011-06-08 69 views
3

我试图实现一个类别表。 简化表描述就像是假设这在其父元素之后排序子元素

id -- name -- parent_id 

的样本数据,如

id - name - parent_id 
1 test1 null 
2 test2 null 
3 test3 null 
4 test4 1 
5 test5 4 
6 test6 2 
7 test7 1 

我挣扎拿出一个SQL查询,将返回按以下顺序设置记录

id - name - parent_id 
1 test1 null 
4 test4 1 
5 test5 4 
7 test7 1 
2 test2 null 
6 test6 2 
3 test3 null 

基本上,子元素在其父元素之后返回。

-----------------------解决方法1:在代码中使用LINQ /递归-------------- -----------

不完全是一个SQL解决方案,但最终它的工作原理。

+2

我不认为有足够的规格。这似乎是任意的,为什么'test1'是'test2'或'test3'之前的父对象。 – 2011-06-08 23:36:48

+2

我可能会错过这一点。但是我看不到样本数据与预期数据顺序之间的关系。 (这是迟到了,所以如果我错过了显而易见的道歉) – lethalMango 2011-06-08 23:37:20

+0

test1应该在测试之前4是他希望根据父亲关系排序,因此test2是有序列表中的下一个ID将是下一个父亲在结果 – Trey 2011-06-08 23:38:19

回答

2

根据您试图对查询进行的操作,您无需对其进行排序。你只需要确保首先创建父母。因此,运行您的查询按父ID排序,将结果放入一个数组并循环访问该数组。在每次迭代时,都要进行检查以确保父代存在,如果它有父代。如果父母不存在,只需将该项目移动到数组的末尾,然后进入下一个,那么最后只能看到一些移动的案例,因此它仍然非常有效。

1

我过去一直在做的事情是把数据库分成以下几部分(尽管我可能还有其他一些解决方案,但我并不是最好的)。

categories 
- category_id | int(11) | Primary Key/Auto_Increment 
.. 
.. 

sub_categories 
- sub_category_id | int(11) | Primary Key/Auto_Increment 
- category_id  | int(11) | Foreign Key to categories table 
.. 
.. 
1

通过以下作品中的查询增加了一个额外order_parent列中包含的任何父ID或该行的ID,这取决于它是否是父。然后,它主要根据order_parent ID对它们进行分组,然后通过parent_idnull(实际父母)进行排序。

两件事情:

  1. 这又多了一个,你本来想列,因此就忽视它。
  2. 如果您的数据库最后返回parent_id的nulls,请添加DESC

好的问题,顺便说一下!

SELECT id, 
     name, 
     parent_id, 
     (
      case 
      when parent_id is null then id 
      else parent_id 
      end 
     ) AS order_parent 
FROM  myTable 
ORDER BY order_parent, parent_id 
+0

你运行这个查询吗?它排序的孩子,但孙子(id = 5)最后结束 – Bohemian 2011-06-09 00:04:37

+0

啊,孙子。相当。我没有注意到这些。 – 2011-06-09 00:09:16

+0

你试图运行它。它看起来即将工作。但实际上并没有工作。为了简单起见(为了避免空值),我将ID复制到没有父节点的节点的父节点字段中。 – robert 2011-06-09 00:09:51

1

这里是我会做什么:

SELECT id, name, parent_id, (CASE WHEN COALESCE(parentid,0)=0 THEN id ELSE (parentid + '.' + id)) as orderid 
FROM table 
ORDER BY (CASE WHEN COALESCE(parentid,0)=0 THEN id ELSE (parentid + '.' + id)) 

这应该创建一个新列名为订单ID具有的parentid点的ID(1.4,4.5,等)列在父id为null,它会放上id。这样你会得到的订单为1,1.4,4,4.5等。

请检查代码,因为我没有测试就这么写。它应该接近。