Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

zdobądź wszystkie zagnieżdżone dzieci dla identyfikatora rodzica

Ten bałagan tworzy wynik próbki z danych próbki. Nadal nie jest jasne, co ty uważam, że algorytm powinien być.

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;

Podejrzewam, że problem polega na tym, że pomieszałeś swoje dane w nierówny sposób. Hierarchia kategorii jest zwykle reprezentowana w następujący sposób:

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

Korzeń każdej hierarchii jest wskazywany przez ParentCategoryId is NULL . Pozwala to na współistnienie dowolnej liczby niezależnych drzew w jednej tabeli i nie zależy od istnienia jakichkolwiek produktów.

Jeśli produkty są przypisane do jednej (pod)kategorii, po prostu dołącz CategoryId w Products stół. Jeśli produkt może być przypisany do kilku (pod)kategorii, prawdopodobnie w różnych hierarchiach, użyj oddzielnej tabeli, aby je powiązać:

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. Wyjątek 0x80040154 wygenerowany podczas wykonywania prostego pakietu ssis w środowisku MS SQL 2008R2

  2. wyświetlić zmienione wartości po zaktualizowaniu instrukcji

  3. Wstaw dane do widoku (SQL Server)

  4. SQL Server 2016:Wstaw dane

  5. Jak pomnożyć wszystkie wartości w kolumnie za pomocą SQL, takiego jak SUM()