2015-01-22 3 views
3

позволяет сказать, что я должен хранить следующую информацию в моей базе данных, enter image description hereтаблицы иерархии Проектирование

Теперь мои таблицы базы данных будут разработаны и структурированы так, enter image description here

В более поздний срок, если Мне пришлось добавить еще один уровень подкатегории, как я смогу достичь этого, не изменив структуру базы данных вообще?

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

Может кто-нибудь, пожалуйста, просветить меня или вести меня в правильном направлении? Заранее спасибо ...

:)

+0

Используйте таблицу с иерархией, которая имеет родительское отношение ребенка –

ответ

4

Было бы трудно добавить столбцы в таблицу, когда новые уровни должны быть сгенерированы. Лучший способ - использовать 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

enter image description here

В таблице категорий, вы можете добавить категории для 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) 

Вот результат из приведенного выше запроса

enter image description here

Пояснение

  • 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 
  • Click here для просмотра результата

Вы получите результат ниже после поворота

enter image description here

ПРИМЕЧАНИЯ

  1. Если вы хотите, чтобы все записи были независимо от предмета, удалите пункт WHERE внутри CTE. Click here для просмотра результата.

  2. Теперь я предоставил порядок столбцов в сводной таблице как DESC, т. Е. Показывает его родительский уровень верхнего уровня ..... Родитель объекта. Если вы хотите сначала показать родителя элемента, а затем следующий уровень и верхний уровень, вы можете изменить DESC внутри ROW_NUMBER() на ASC. Click here для просмотра результата.

+0

У меня есть обновление. Пожалуйста, проверьте. @Gayanee Wijayasekara –

+0

Вам нужно показать сводный отчет? Например, элемент, его основная категория и его подкатегории ... вот так? @Gayanee Wijayasekara –

+0

Благодарим вас за быстрый ответ. :) Да Мне нужно иметь все детали категорий, чтобы я мог позже фильтровать детали и находить записи на основе критериев выбора. @ Sarath Avanavu –

-1

Для того, чтобы добавить новую подкатегорию, следует добавить категорию в таблицу «ItemSubCategory1» после этого вы можете легко добавить его в таблицу «Напитки».

Для примера: Если есть новое название категории «Горячие напитки» и новый пункт «Кофе», который входит в Beverages основной категории (пусть CatID = 1, MainCatText = «Напитки» в ItemMainCategory таблицы), то

INSERT INTO ItemSubCategory1(CatId,SubCatText) VALUES(4,'Hot Drinks') 

INSERT INTO Drinks(ItemId,ItemName,ItemMainCategory,ItemSubCategory) 
VALUES(5,'Coffee',1,4) 
3

В соответствии с вашей схемой нет никакой связи между «основной категорией» и «подкатегорией», но ваши данные выборки предполагают наличие отношений, то есть Alcohol IS A Beverage и т. Д. Это звучит как иерархия категорий, в которой в случае, если бы вы могли вместо этого выбрать одну таблицу категорий для самостоятельной привязки;

create table dbo.Category (
    CategoryID int not null constraint PK_Category primary key clustered (CategoryID), 
    ParentCategoryID int not null, 
    CategoryName varchar(100) not null 
) 

alter table dbo.Category add constraint FK_Category_Category foreign key(ParentCategoryID) references dbo.Category (CategoryID) 

insert dbo.Category values (1, 1, 'Beverages') 
insert dbo.Category values (2, 1, 'Soft Drink') 
insert dbo.Category values (3, 1, 'Alcohol') 

Таким образом, вы можете создать столько уровней, сколько хотите. Любая категория, где ParentCategoryID = CategoryID - категория верхнего уровня.

Надеется, что это помогает,

Rhys

+0

Вы могли бы в равной степени использовать 'NULL' и' ParentCategoryID' представляют собой основную категорию. Это личное предпочтение, но я думаю, что это делает более очевидным, что это категория верхнего уровня, чем сравнивать его с «CategoryID». – Tony

+0

Благодарим вас за быстрый ответ. Я рассмотрю этот метод, чтобы узнать, могу ли я управлять своими требованиями, используя это. :) @Rhys –

Смежные вопросы