2016-05-20 3 views
2

У меня есть категория table, которая имеет поле int, которое может ссылаться на primary key в той же таблице.sql complex order by multiple fields

так:

ID category   isSubCategoryOf orderingNumber 
3 "red t-shirts"   2    2 
1 "clothes"    NULL   1 
4 "cars"    NULL   1 
6 "Baby toys"   5    1 
5 "Toys"    NULL   1 
2 "t-shirt"    1    1 

Я хочу table быть порядок таким образом, что в каждой категории всех подкатегории перечислены и в соответствии с этой категорией всех этих подкатегорий.

ID category   isSubCategoryOf orderingNumber 
1 "clothes"    NULL   1 
2 "t-shirt"    1    1 
3 "red t-shirts"   2    2 
4 "cars"    NULL   1 
5 "Toys"    NULL   1 
6 "Baby toys"   5    1 

ли такое возможно сделать с SQL или я должен заказать позже вручную?

+0

могли бы вы дать нам пример? –

+0

Вы можете опубликовать фактические данные таблицы? – bmsqldev

+0

@bmsqldev Имеются фактические данные таблицы. –

ответ

4

Я понимаю ваши потребности правильно, вам нужен рекурсивный запрос, чтобы иметь дело с иерархическими данными:

WITH recCTE AS 
(

    --recursive seed 
    SELECT 
     category, 
     ID, 
     isSubCategoryOf as ParentID, 
     orderingNumber, 
     CAST(ID as VARCHAR(100)) as Path, 
     1 as depth 
    FROM table 
    WHERE isSubCategoryOf IS NULL 

    UNION ALL 

    --recursive term 
    SELECT 
     table.category, 
     table.id, 
     table.isSubCategoryOf, 
     table.orderingNumber, 
     recCTE.path + '>' + table.id, 
     recCTE.depth + 1 
    FROM recCTE 
     INNER JOIN table ON 
      recCTE.ID = table.isSubCategoryOf 
) 

SELECT * FROM recCTE ORDER BY path 

Рекурсивных запросы состоят из трех частей.

  1. Рекурсивное семя, которое является исходной точкой рекурсивного поиска. В вашем случае это любая запись с NULL isSubCategoryOf. Вы можете думать об этом как о корне вашей иерархии.

  2. Рекурсивный термин, который является частью рекурсивного КТР, который ссылается на себя. Он выполняет итерацию до тех пор, пока не появится запись для каждой ножки иерархии.

  3. Последняя инструкция Select, которая выбирает из рекурсивного CTE.

Здесь я создал поле пути, которое сшивает каждый идентификатор, который является частью гиархики. Это дает вам поле, в котором вы можете сортировать, чтобы получить свой иерархический вид в соответствии с запросом.

Похоже, что ваши данные orderingNumber сродни полюсу depth, который я добавил к рекурсивному CTE выше. Если это так, вы можете удалить это поле из CTE и сохранить немного обработки.

+0

Спасибо за помощь. Кажется, я не могу запустить его. Я понимаю ваше объяснение, но я не могу запустить запрос: Неправильный синтаксис рядом с 'recCTE'. –

+0

Является ли это SQL-сервером, на котором вы работаете, или с помощью другой СУБД, например, MySQL или что-то еще? Если это сервер SQL, в какой версии вы работаете? – JNevill

+0

На самом деле ... если это SQL-сервер, удалите ключевое слово 'RECURSIVE' вверху. Just: 'WITH recCTE' Я получаю мой синтаксис, перепутанный между разными БД:/Я отредактировал ответ, чтобы отразить это изменение. – JNevill

0

, если вы просто хотите sotrt и распечатать вы можете сделать вычисляемый столбец

select ID, category, isSubCategoryOf, orderingNumber, ID + '_' + isSubCategoryOf as SortOrder 
    from table 
    order by ID + '_' + isSubCategoryOf 
+0

Я не думаю, что это будет работать на потребности OP, хотя с небольшими показателями образцов, это будет. Кроме того, я считаю, что 'order by ID, isSubCategoryOf' будет работать так же хорошо и не потребует от БД конкатентных полей, сохраняя некоторый процессор. – JNevill

+0

Да, вы правы. Мой запрос возвращает неверный результат для вопроса и может быть просто использован как иллюстрация. – xdd