Я должен следующие данные в SQL Server 2008 R2. SQLFiddle
Схема:
CREATE TABLE [dbo]. [ICFilters] ( [ICFilterID] [int] IDENTITY (1,1) НЕ NULL, [ParentID] [int] НЕ NULL ПО УМОЛЧАНИЮ 0, [FilterDesc] [varchar] (50) NOT NULL, [Активный] [tinyint] НЕ NULL ПО УМОЛЧАНИЮ 1, CONSTRAINT [PK_ICFilters] ПЕРВИЧНЫЙ КЛЮЧ КЛАСТЕР ([ICFilterID] ASC) С PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON ) НА [ПЕРВИЧНО] ) НА [ПЕРВИЧНО] INSERT INTO [dbo]. [ICFilters] (ParentID, FilterDesc, Active) Ценности (0, «Тип продукта», 1), (1, 'ProdSubType_1', 1), (1, 'ProdSubType_2', 1), (1, 'ProdSubType_3', 1), (1, 'ProdSubType_4', 1), (2, 'PST_1.1', 1), (2, 'PST_1.2', 1), (2, 'PST_1.3', 1), (2, 'PST_1.4', 1), (2, 'PST_1.5', 1), (2, 'PST_1.6', 1), (2, 'PST_1.7', 0), (3, 'PST_2.1', 1), (3, 'PST_2.2', 0), (3, 'PST_2.3', 1), (3, 'PST_2.4', 1), (14, 'PST_2.2.1', 1), (14, 'PST_2.2.2', 1), (14, 'PST_2.2.3', 1), (3, 'PST_2.8', 1)
Стол:
| ICFILTERID | PARENTID | FILTERDESC | ACTIVE | -------------------------------------------------- | 1 | 0 | Тип продукта | 1 | | 2 | 1 | ProdSubType_1 | 1 | | 3 | 1 | ProdSubType_2 | 1 | | 4 | 1 | ProdSubType_3 | 1 | | 5 | 1 | ProdSubType_4 | 1 | | 6 | 2 | PST_1.1 | 1 | | 7 | 2 | PST_1.2 | 1 | | 8 | 2 | PST_1.3 | 1 | | 9 | 2 | PST_1.4 | 1 | | 10 | 2 | PST_1,5 | 1 | | 11 | 2 | PST_1.6 | 1 | | 12 | 2 | PST_1.7 | 0 | | 13 | 3 | PST_2.1 | 1 | | 14 | 3 | PST_2.2 | 0 | | 15 | 3 | PST_2.3 | 1 | | 16 | 3 | PST_2.4 | 1 | | 17 | 14 | PST_2.2.1 | 1 | | 18 | 14 | PST_2.2.2 | 1 | | 19 | 14 | PST_2.2.3 | 1 | | 20 | 3 | PST_2.8 | 1 |
Каждая строка имеет идентификатор своего родителя и корня parentid = 0
. Это FilterDesc
просто примеры описаний, поэтому я не могу разобрать их при заказе.
Вопрос
Можно ли выбрать все строки в древовидной форме? Если да, то как? Когда я говорю «древовидный», я имею в виду рекурсивный выбор родителя, за которым следуют все его потомки, затем все потомки каждого из них и так далее. Глубина первого обхода дерева.
Мои друзья и я пытались, но у нас не хватило рабочих решений, но мы будем продолжать пытаться. Я довольно новичок в SQL, поэтому, возможно, это можно сделать легко, и я просто усложняю, чем нужно.
Пример (желаемый) вывод:
| ICFILTERID | PARENTID | FILTERDESC | ACTIVE | -------------------------------------------------- | 1 | 0 | Тип продукта | 1 | | 2 | 1 | ProdSubType_1 | 1 | | 6 | 2 | PST_1.1 | 1 | | 7 | 2 | PST_1.2 | 1 | | 8 | 2 | PST_1.3 | 1 | | 9 | 2 | PST_1.4 | 1 | | 10 | 2 | PST_1,5 | 1 | | 11 | 2 | PST_1.6 | 1 | | 12 | 2 | PST_1.7 | 0 | | 3 | 1 | ProdSubType_2 | 1 | | 13 | 3 | PST_2.1 | 1 | | 14 | 3 | PST_2.2 | 0 | | 17 | 14 | PST_2.2.1 | 1 | | 18 | 14 | PST_2.2.2 | 1 | | 19 | 14 | PST_2.2.3 | 1 | | 15 | 3 | PST_2.3 | 1 | | 16 | 3 | PST_2.4 | 1 | | 20 | 3 | PST_2.8 | 1 | | 4 | 1 | ProdSubType_3 | 1 | | 5 | 1 | ProdSubType_4 | 1 |
sql-server
sql-server-2008-r2
order-by
hierarchy
Archangel33
источник
источник
Ответы:
Хорошо, достаточно клеток мозга мертвы.
SQL Fiddle
источник
[FilterDesc]
столбце являются вымышленными, и этот порядок не нужен / не важен. Следуя логике в ответе @Travis Gan, все, что нужно сделать, чтобы получить этот порядок, это добавить еще одинCAST
кLevel
. например.Level + CAST( CAST(i.[ICFilterID] AS varbinary(max)) AS Level
СтановитсяLevel + CAST(i.[FilterDesc] AS varbinary(max)) + CAST(i.[ICFilterID] AS varbinary(max)) AS Level
.Выше, кажется, не работает правильно для меня. Представьте себе 2 таблицы настройки с типом данных facebook. Таблица 1, имеет PostId + другие поля. PostId - это автоинкремент, и, очевидно, в вашем интерфейсе вы будете сортировать DESC, чтобы иметь самый последний пост в верхней части.
Теперь для таблицы комментариев. Таблица 2 Эта таблица CommentId является первичным ключом, автоматическим номером. В вашем графическом интерфейсе вы хотите отобразить его ASC, чтобы при чтении потока это имело смысл. (самый старый (меньшее число) вверху). Другими важными ключами в таблице 2 являются: PostId (FK назад к сообщениям) и ParentId (от FK до CommentId), где ParentId будет иметь значение NULL, если это «корневой» комментарий к сообщению. Если кто-то ОТВЕТИТ на комментарий, то parentId будет заполнен комментарием.
Надеюсь, вы, ребята, поняли. CTE будет выглядеть так:
Образец вывода
На пост F / B 105 было два комментария (CommentIds 1 и 2). Затем кто-то ответил на Comment1 (CommentId 5, ParentId 1), а затем кто-то прокомментировал этот ответ, так что Comment5 (CommentId 6, ParentId 6)
И альт, последовательность правильная, под постом теперь можно показывать комментарии в правильной последовательности. Чтобы сделать отступ для постов так, чтобы они формировались и обрисовывались, как в Facebook (чем глубже уровень, тем больше он должен быть слева), у меня также есть столбец «Отступ». Корни равны 0, а затем в объединении мы имеем c.Indent + 1 AS Отступ В коде yo теперь может умножить отступ с помощью предположения 32px и показать комментарии в хорошей иерархии и набросках.
Я не вижу проблем с использованием первичного ключа с автоинкрементом CommentId в качестве движущей силы для создания моего SortKey, поскольку лучше изменить время, когда вы путаете даты (commentdate), чем путать ключ, управляемый базой данных, который начинается с +1
источник
Это даст вам всех потомков и уровень.
Надеюсь это поможет :)
источник