2013-09-03 3 views
0

Started Fiddlingполучить все вложенные ребенок для родительского идентификатора

Work Table 
ProductId, LabelName, CategoryId, ChildCategoryId 
------------------------------------ 
1, Widget A, 1, null 
null, Category A, 2, 1 
2, Widget B, 3, null 

Categories Table 
CategoryId, CategoryName 
--------------------------- 
1, Category A 
2, Category B 
3, Category C 

Учитывая информацию выше, как бы вы получите все категории для идентификатора продукта?

Например, если идентификатор продукта равен 1, то будут получены следующие результаты.

Desired Results 
ProductId, LabelName, CategoryId, ChildCategoryId 
------------------------------------ 
1, Widget A, 1, null 
null, Category A, 2, 1 
null, Category B, null, 2 

Предполагается, что это иерархические данные, и я приношу свои извинения за то, что не смог объяснить очень хорошо. Это просто ошеломляет меня. Виджет A имеет идентификатор продукта 1 и идентификатор категории 1. Это означает, что все записи, содержащие ChildCategoryId из 1, включены, что дает нам категорию A. CatA имеет идентификатор категории 2, как и раньше, все записи, которые имеют ChildCategoryId из 2 включен в результат, поэтому категория B включена.

+0

Можете ли вы объяснить, как вы прибудете на желаемых результатов от данных выборки вы предоставлена? И куда входит 'associationTable'? – HABO

+0

Я перечислил таблицу объединений в таблицу транзакций, чтобы быть немного более понятной. Возможно, не сработало. Это не главная таблица или таблица соединений. Думаю, это похоже на таблицу результатов. – Rod

+0

Категория B относится к виджету A по категории A. Вторая запись в таблице транзакций показывает, что категория A имеет присвоенный ей идентификатор категории 2. – Rod

ответ

1

Этот беспорядок производит результат выборки из данных образца. Пока неясно, что вы думаете, что алгоритм должен быть.

declare @CategoryItems as Table (
    CategoryName NVarChar(255), 
    Label NVarChar(255), 
    ProductId Int, 
    ChildCategoryId Int, 
    CategoryId Int); 

declare @Categories as Table (
    CategoryId Int, 
    Name NVarChar(100)); 

insert into @CategoryItems (CategoryName, Label, ProductId, ChildCategoryId, CategoryId) values 
    ('CategoryA', 'Widget A', 1, 0, 1), 
    ('CategoryB', 'CategoryA', 0, 1, 2), 
    ('CategoryC', 'Widget B', 2, 0, 3); 
insert into @Categories (CategoryId, Name) values 
    (1, 'CategoryA'), 
    (2, 'CategoryB'), 
    (3, 'CategoryC'); 

select * from @Categories; 
select * from @CategoryItems; 

declare @TargetProductId as Int = 1; 

with Leonard as (
    -- Start with the target product. 
    select 1 as [Row], ProductId, Label, CategoryId, ChildCategoryId 
    from @CategoryItems 
    where ProductId = @TargetProductId 
    union all 
    -- Add each level of child category. 
    select L.Row + 1, NULL, CI.Label, CI.CategoryId, CI.ChildCategoryId 
    from @CategoryItems as CI inner join 
     Leonard as L on L.CategoryId = CI.ChildCategoryId), 
    Gertrude as (
    -- Take everything that makes sense. 
    select Row, ProductId, Label, CategoryId, ChildCategoryId 
     from Leonard 
    union 
    -- Then tack on an extra row for good measure. 
    select L.Row + 1, NULL, C.Name, NULL, C.CategoryId 
     from Leonard as L inner join 
     @Categories as C on C.CategoryId = L.CategoryId 
     where L.Row = (select Max(Row) from Leonard)) 
    select Row, ProductId, Label, CategoryId, ChildCategoryId 
    from Gertrude 
    order by Row; 

Я подозреваю, что проблема в том, что вы смешали свои данные в одностороннем порядке. Иерархия категорий Usally представляла собой нечто вроде:

declare @Categories as Table (
    CategoryId Int Identity, 
    Category NVarChar(128), 
    ParentCategoryId Int Null); 

Корня каждой иерархии обозначенного ParentCategoryId is NULL. Это позволяет любому количеству независимых деревьев сосуществовать в одной таблице и не зависит от существования каких-либо продуктов.

Если продукты относятся к одной (вспомогательной) категории, то просто укажите CategoryId в таблице Products. Если продукт может быть присвоен нескольким (суб) категории, возможно, в разных иерархий, а затем использовать отдельную таблицу, чтобы связать их:

declare @ProductCategories as Table (
    ProductId Int, 
    CategoryId Int); 
+0

Кто-нибудь знает ссылку на ресурс или пример рекурсивного SQL-запроса не-cte – Rod

+0

@Rod - AFAIK, единственный способ реализовать _recursive query_ в TSQL - это CTE. Вы можете реализовать _recursion_, используя цикл и временную таблицу (ы), курсоры необязательные или, возможно, с табличной функцией. Почему вы спрашиваете? – HABO

+0

Только для учебных целей – Rod

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