Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

вземете всички вложени деца за идентификатор на родител

Тази бъркотия произвежда примерния резултат от примерните данни. Все още не е ясно какво ти мисля, че алгоритъмът трябва да бъде.

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;

Подозирам, че проблемът е, че сте смесили данните си по неравномерен начин. Йерархията от категории обикновено се представя като:

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 );



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server:Каква е разликата между CROSS JOIN и FULL OUTER JOIN?

  2. Sql съхранена процедура с много параметри

  3. Как мога да проверя за дубликати преди вмъкване в таблица при вмъкване чрез избиране

  4. Как да генерирате скрипт, за да активирате всички ограничения на външния ключ в базата данни на SQL Server - SQL Server / TSQL Урок, част 78

  5. Изтриване на пощенски акаунт в база данни в SQL Server (T-SQL)