【问题标题】:Sort data in SQL Server based on parent child relationSQL Server 根据父子关系对数据进行排序
【发布时间】:2019-09-28 19:07:58
【问题描述】:

我有一个表格,用于存储章节的详细信息,我必须按照索引表的顺序显示数据

  1. 第一章

    1.1 第一章第1页

    1.2 第一章第2页

  2. 第二章

    2.1 第二章第1页

    2.2 第二章第2页

  3. 第三章

    标题一

    标题二

    标题三

    3.1 第三章第1页

    3.2 第三章第2页

    3.3 第三章第三页

我们可以按排序或未排序的顺序将数据插入数据库。但是数据应该根据父子页面的 pageOrder 以排序顺序显示

我已经设置了 SQL Fiddle,但由于某种原因我无法保存 SQL。您将在下面找到小提琴链接和详细信息

CREATE TABLE [Book]
(
     [id] int, 
     [Chapter] varchar(20), 
     [PageOrder] int, 
     [parentID] int
);

INSERT INTO [Book] ([id], [Chapter], [PageOrder],  [parentID])
VALUES
    ('1', 'Chapter One', 1, 0),
    ('2', 'Chapter Two', 2, 0),
    ('3', 'Chapter Three', 3, 0),
    ('4', 'Chapter Four', 4, 0),
    ('5', 'Chapter Five', 5, 0),
    ('6', 'Chapter One Page 1', 1, 1),
    ('7', 'Chapter One Page 2', 2, 1),
    ('8', 'Chapter One Page 3', 3, 1),
    ('9', 'Chapter One Page 4', 4, 1),
    ('10', 'Chapter Two Page 1', 1, 2),
    ('11', 'Chapter Two Page 3', 3, 2),
    ('12', 'Chapter Two Page 2', 2, 2),
    ('13', 'Chapter Three Tite 1', 0, 3),
    ('14', 'Chapter Three Tite 2', 0, 3),
    ('15', 'Chapter Three Tite 3', 0, 3),
    ('16', 'Chapter Three Page 2', 2, 3),
    ('17', 'Chapter Three Page 3', 3, 3),
    ('18', 'Chapter Three Page 1', 1, 3);

WITH CTE(ID, parentID, Chapter, PageOrder, Depth, SortCol) AS  
( 
    SELECT 
        ID, parentID, Chapter, PageOrder, 0, 
        CAST(ID AS varbinary(max)) 
    FROM Book 
    WHERE parentID = 0 

    UNION ALL

    SELECT 
        d.ID, d.parentID, d.Chapter, d.PageOrder, p.Depth + 1, 
        CAST(SortCol + CAST(d.ID AS binary(4)) AS varbinary(max)) 
    FROM Book AS d 
    JOIN CTE AS p ON d.parentID = p.ID 
) 
SELECT 
    ID, parentID, Chapter, PageOrder, Depth, 
    REPLICATE('--', Depth) + Chapter as PageName 
FROM CTE 
ORDER BY SortCol

此 CTE 查询正在对数据进行排序,但子页面未正确排序 子页面以它们保存在数据库中的排序顺序显示

SqlFiddle 链接http://www.sqlfiddle.com/#!3/9770a/1

【问题讨论】:

  • For ('12','Chapter Two Page 2', 2, 1) 记录的父 ID 是 2 还是 1 可以确认吗?因为你的页面顺序是第 2 章下的 2 所以。
  • 是的,你是对的,改变它的事件 tow 2 不会对结果产生任何改变

标签: sql sql-server sql-server-2008


【解决方案1】:

完整的解决方案,如

SELECT * FROM
    (
     SELECT p.CategoryID
       , p.Category_Name
       , p.IsParent
       , p.ParentID
       , p.Active
       , p.Sort_Order AS Primary_Sort_Order
       , CASE WHEN p.IsParent = 0 THEN (SELECT Sort_Order FROM tbl_Category WHERE 
     CategoryID = p.ParentID) ELSE p.Sort_Order END AS Secondary_Sort_Order
      FROM tbl_Category p
    ) x
    ORDER BY Secondary_Sort_Order,
            CASE WHEN ParentID = 0 THEN CategoryID ELSE ParentID END,
CASE WHEN ParentID = 0 THEN 0 ELSE Primary_Sort_Order END, Primary_Sort_Order ASC

希望对您有所帮助....!

【讨论】:

    【解决方案2】:

    使用PageOrder而不是ID来构建SortCol,也可以转换为VARCHAR(MAX)而不是VARBINARY(MAX)

    WITH CTE(ID, parentID, Chapter, PageOrder, Depth, SortCol)  AS  ( 
      SELECT ID, parentID, Chapter,PageOrder, 0, 
             CAST(PageOrder AS varchar(max)) 
      FROM Book 
      WHERE parentID = 0 
    
      UNION ALL
    
      SELECT d.ID, d.parentID, d.Chapter, d.PageOrder, p.Depth + 1, 
      CAST(SortCol + CAST(d.PageOrder AS varchar(max)) AS varchar(max)) 
      FROM Book AS d 
      JOIN CTE AS p ON d.parentID = p.ID 
    )   
    SELECT ID, parentID, Chapter, PageOrder, Depth, SortCol,
           REPLICATE('--', Depth) + Chapter as PageName 
    FROM CTE 
    ORDER BY SortCol, Chapter
    

    另外Chapter 列用于对具有相同PageOrder 且属于同一树级别的章节进行排序。

    Demo here

    【讨论】:

      【解决方案3】:
      SELECT *, REPLICATE('--', CASE WHEN parentID > 0 THEN 1 ELSE 0 END) + Chapter AS PageName 
      FROM Book 
      ORDER BY COALESCE(NULLIF(parentID,0), id), parentID, PageOrder
      

      【讨论】:

        猜你喜欢
        • 2016-12-31
        • 2019-02-23
        • 1970-01-01
        • 1970-01-01
        • 2020-03-07
        • 1970-01-01
        • 2019-01-22
        • 2018-07-31
        • 2021-03-21
        相关资源
        最近更新 更多