Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

lấy tất cả các con lồng nhau cho một id cha

Sự lộn xộn này tạo ra kết quả mẫu từ dữ liệu mẫu. Vẫn chưa rõ bạn là gì nghĩ rằng thuật toán phải như vậy.

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;

Tôi nghi ngờ rằng vấn đề là bạn đã trộn dữ liệu của mình theo cách khác nhau. Hệ thống phân cấp các danh mục thường được đại diện như sau:

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

Gốc của mỗi cấu trúc phân cấp được chỉ ra bởi ParentCategoryId is NULL . Điều này cho phép bất kỳ số lượng cây độc lập nào cùng tồn tại trong một bảng duy nhất và không phụ thuộc vào sự tồn tại của bất kỳ sản phẩm nào.

Nếu sản phẩm được chỉ định cho một danh mục (phụ) thì chỉ cần bao gồm CategoryId trong Products bàn. Nếu một sản phẩm có thể được gán cho một số danh mục (phụ), có thể ở các thứ bậc khác nhau, thì hãy sử dụng một bảng riêng để liên kết chúng:

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. Làm cách nào để truy vấn và phân tích cú pháp phân cấp danh sách liền kề bằng cte?

  2. 2 Cách Kiểm tra xem Truy cập Dữ liệu có được Bật trong SQL Server hay không (Ví dụ T-SQL)

  3. Loại dữ liệu được trả về thay đổi dựa trên dữ liệu trong bảng

  4. Cách sử dụng SQL Server Hàm T-SQL SUM:5 Trường hợp sử dụng

  5. Thuộc tính xml truy vấn SQL Server cho một giá trị phần tử