Было бы трудно добавить столбцы в таблицу, когда новые уровни должны быть сгенерированы. Лучший способ - использовать Hierarchy table
для поддержания Parent-Child relationship
.
Таблица: Items
x----x------------------x------------x
| ID | Items | CategoryId |
|----x------------------x------------x
| 1 | Pepsi | 3 |
| 2 | Coke | 3 |
| 3 | Wine | 4 |
| 4 | Beer | 4 |
| 5 | Meals | 2 |
| 6 | Fried Rice | 2 |
| 7 | Black Forest | 7 |
| 8 | XMas Cake | 7 |
| 9 | Pinapple Juice | 8 |
| 10 | Apple Juice | 8 |
x----x------------------x------------x
Таблица: Category
В таблице категорий, вы можете добавить категории для n
уровней. В таблице Items
вы можете сохранить категорию самого низкого уровня. Например, возьмите случай Pepsi
- его categoryId
- 3. В таблице Category вы можете найти своего родителя, используя JOIN
s и найти родителей родителей, используя запросы иерархии.
В Category
таблице категории с ParentId
равна нулю (то есть без каких-либо ParentID) будут MainCategory
и другие предметы с ParentId
будут находиться под SubCategory
.
EDIT:
Любой, как вам нужно изменить таблицы, потому что в соответствии с текущей схемой, вы не можете добавить столбец первой таблицы, так как количество подкатегорий может продолжать меняться. Даже если вы создаете таблицу в соответствии с Ответы Rhys Jones, вам нужно соединить две таблицы со строкой. Проблема при соединении со строкой заключается в том, что при необходимости изменить имя Sub category
или Main category
вы должны изменить в каждой таблице, в которой вы попадете в неприятности в будущем, и не является хорошим дизайном базы данных. Поэтому я предлагаю вам следовать приведенной ниже схеме.
Вот запрос, который дает родителям детские предметы.
DECLARE @ITEM VARCHAR(30) = 'Black Forest'
;WITH CTE AS
(
-- Finds the original parent for an ITEM ie, Black Forest
SELECT I.ID,I.ITEMS,C.CategoryId,C.Category,ParentId,0 [LEVEL]
FROM #ITEMS I
JOIN #Category C ON I.CategoryId=C.CategoryId
WHERE ITEMS = @ITEM
UNION ALL
-- Now it finds the parents with hierarchy level for ITEM
-- ie, Black Forest. This is called Recursive query, which works like loop
SELECT I.ID,I.ITEMS,C.CategoryId,C.Category,C.ParentId,[LEVEL] + 1
FROM CTE I
JOIN #Category C ON C.CategoryId=I.ParentId
)
-- Here we keep a column to show header for pivoting ie, CATEGORY0,CATEGORY1 etc
-- and keep these records in a temporary table #NEWTABLE
SELECT ID,ITEMS,CATEGORYID,CATEGORY,PARENTID,
'CATEGORY'+CAST(ROW_NUMBER() OVER(PARTITION BY ITEMS ORDER BY [LEVEL] DESC)-1 AS VARCHAR(4)) COLS,
ROW_NUMBER() OVER(PARTITION BY ITEMS ORDER BY [LEVEL] DESC)-1 [LEVEL]
INTO #NEWTABLE
FROM CTE
ORDER BY ITEMS,[LEVEL]
OPTION(MAXRECURSION 0)
Вот результат из приведенного выше запроса
Пояснение
Black Forest
подпадает под Cake
.
Cake
Подходит под Bakery
.
Bakery
Подходит под Food
.
Вроде бы вы можете создать детей или родителей для любого количества уровней. Теперь, если вы хотите добавить родитель Food
и Beverage
, в течение, например, Food Industry
, просто добавьте Food Industry
к Category
таблицы и сохранить Food Industry's
Id как ParentId
для Food
и Beverage
. Это все.
Теперь, если вы хотите сделать поворот, вы можете выполнить приведенные ниже процедуры.
1. Получите значения из столбца, чтобы показать, как эти значения в столбце поворота
DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',[' + COLS + ']', '[' + COLS + ']')
FROM (SELECT DISTINCT COLS,[LEVEL] FROM #NEWTABLE) PV
ORDER BY [LEVEL]
2.Теперь используйте ниже PIVOT запрос
DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT * FROM
(
SELECT ITEMS, CATEGORY, COLS
FROM #NEWTABLE
) x
PIVOT
(
MIN(CATEGORY)
FOR COLS IN (' + @cols + ')
) p
ORDER BY ITEMS;'
EXEC SP_EXECUTESQL @query
Вы получите результат ниже после поворота
ПРИМЕЧАНИЯ
Если вы хотите, чтобы все записи были независимо от предмета, удалите пункт WHERE
внутри CTE
. Click here для просмотра результата.
Теперь я предоставил порядок столбцов в сводной таблице как DESC
, т. Е. Показывает его родительский уровень верхнего уровня ..... Родитель объекта. Если вы хотите сначала показать родителя элемента, а затем следующий уровень и верхний уровень, вы можете изменить DESC
внутри ROW_NUMBER()
на ASC
. Click here для просмотра результата.
Используйте таблицу с иерархией, которая имеет родительское отношение ребенка –