2015-06-16 3 views
0

Скажем, у меня есть уверенность ссылки таблицу, как это одинПоказать Чайлдс после их родителей в себя родительскую таблицу

------------------------------ 
| ID | Name  | ParentID | 
| 1 | Fruits  |   | 
| 2 | Vegetables |   | 
| 3 | Animals |   | 
| 4 | Whatever |   | 
| 6 | Orange  | 1  | 
| 7 | Apple  | 1  | 
| 8 | Banana  | 1  | 
------------------------------ 

мне нужно сделать запрос, чтобы извлечь данные следующим образом:

------------------------------ 
| ID | Name  | ParentID | 
| 1 | Fruits  |   | 
| 6 | Orange  | 1  | 
| 7 | Apple  | 1  | 
| 8 | Banana  | 1  | 
| 2 | Vegetables |   | 
| 3 | Animals |   | 
| 4 | Whatever |   | 
------------------------------ 

Показан родительский элемент перед ребенком, когда он применяется.

+1

Какой поставщик базы данных вы используете? –

+0

http://sqlfiddle.com/#!9/2a3d6/1 – Javaluca

ответ

2

Предполагая, что вы используете какой-то вариант SQL Server, необходимо использовать общее выражение таблицы с какой-то путь/колонки крошек включены ...

;with cte as 
(
    select Id, Name, ParentID, 
      convert(nvarchar(max), [Id]) as Breadcrumb 
    from dbo.Location 
    where ParentID is null 
    -- 
    union all 
    -- 
    select l.Id, l.Name, l.ParentID, 
      cte.BreadCrumb + '\' + convert(nvarchar(max), l.[Id]) as Breadcrumb 
    from dbo.Location l 
    inner join cte on l.ParentId = cte.Id 
) 

select * 
    from cte 
order by Breadcrumb 

Edit: Вы можете использовать ID или Имя как ваше значение для панировки - зависит от того, как вы действительно хотите сортировать данные.

0

Если SQL-сервер:

select * from MyTable 
order by 
case when ID in (select distinct parentID from MyTable) 
    then ID - 0.5 else isnull(parentID, 100000) end 
, ID 

Проверяет, является ли идентификатор является родителем - если это так, сортирует его чуть выше записей, которые имеют его в качестве родителя (путем вычитания 0,5 из ID).

Примечание: isnull(parentID, 100000) - это просто произвольное большое значение, чтобы отбросить строки, которые не являются родителями, и не имеют родительского элемента в нижней части списка. При необходимости настройте данные на основе данных. Вы можете захотеть заменить 100 000 вычисленным значением на основе самого большого идентификатора в вашей таблице, если у вас много данных и/или они часто меняются.

+0

Мне это нравится. Вопрос: будет ли 'select different' запускаться для каждой строки? – amcdermott

+0

'select distinct', вероятно, не нужно в этом случае, но мне нравится включать его для устранения неполадок (в основном это привычка на данный момент). Я не уверен, что производительность будет иметь значение здесь - непонятно, с какого количества данных обрабатывается. OP может захотеть попробовать с соединением вместо подзапроса, если есть много данных. – APH

+0

Думаю, я мог бы просто заметить недостаток - я не думаю, что это сработает, если идентификатор родительской записи выше, чем у ребенка. Это настоящий позор, если это так, поскольку я думал, что это действительно элегантное решение (и я бы лучше написал это, чем CTE в любой день) – amcdermott