【问题标题】:SQL Union tables into treegrid structure for jqGridSQL联合表到jqGrid的treegrid结构中
【发布时间】:2015-04-24 21:18:24
【问题描述】:

我已经使用我目前拥有的数据库结构创建了一个示例:

here

我的目标是获得一个数据库表,其中所有数据都已经在正确的位置,并以正确的顺序排序,然后输入到 jqGrid 中,最后应该如下所示:

Entity          |OrderTime  |City   |ProductType    |...
-------------------------------------------------------------------
AlexKlar        |           |       |
   SubPack     |17:00      |London |
       Mango   |           |       |Fruit  |
   WelcomePack |15:00      |London |
       Apple   |           |
       Banana  |           |       |Fruit  |
AnnaKlar        |           |       |
   WelcomePack |16:00      |London |
       Apple   |           |       |Fruit  |
JuliaKlar       |           |       |
   PremiumPack |18:00      |London |
       Lychee  |           |       |Fruit  |
   SubPack     |18:30      |London |
       Mango   |           |       |Fruit  |
   WelcomePack |15:00      |London |
       Apple   |           |       |Fruit  |
       Banana  |           |       |Fruit  |

问题 1:将所有表合并到一个主表中以便为 jgGrid 定义 id/parents/level/leaf 的最有效方法是什么?由于并非所有级别都需要所有列的值,因此我必须为其分配一个空字符串 ''。我的代码目前是这样的:

SELECT 
CONVERT(VARCHAR,PersonID) AS id, 
0 AS level, 
'false' AS isLeaf, 
'null' AS parent, 
FullName AS entity,
'' AS OrderTime,
'' AS City,
'' AS Active,
'' AS ProductType,
'' AS Price
from Persons
UNION ALL
SELECT 
CONVERT(VARCHAR,PersonID) + '>' + CONVERT(VARCHAR,OrderID) AS id, 
1 AS level, 
'false' AS isLeaf, 
CONVERT(VARCHAR,PersonID) AS parent, 
OrderName AS entity,
COALESCE(CAST(OrderTime AS VARCHAR(5)),'') AS OrderTime,
City,
Active,
'' AS ProductType,
'' AS Price
from Orders
UNION ALL
SELECT 
CONVERT(VARCHAR,per.PersonID) + '>' + CONVERT(VARCHAR,ord.OrderID) + '>' + CONVERT(VARCHAR,prod.ProductID) AS id, 
2 AS level, 
'true' AS isLeaf, 
CONVERT(VARCHAR,per.PersonID) + '>' + CONVERT(VARCHAR,ord.OrderID) AS parent, 
ProductName AS entity,
'' AS OrderTime,
'' AS City,
so.Completed AS Active,
ProductType,
COALESCE(CONVERT(VARCHAR,Price),'') AS Price
from SubmittedOrders so
INNER JOIN Orders ord ON ord.OrderID = so.OrderID
INNER JOIN Persons per ON per.PersonID = ord.PersonID
INNER JOIN Products prod ON prod.ProductID = so.ProductID
Order by id

问题2:在创建了我拥有的 4 个表的表联合后,我想对其进行排序,使其按字母顺序排列,但仅在它们自己的级别内(使其看起来像上图所示的表)。我想避免使用 jqGrid 内置排序功能 grid.jqGrid('sortGrid', 'importJob');在客户端,因为如果我有 5000 个订单/行,它真的很慢。

提前感谢您的帮助。

【问题讨论】:

    标签: sql-server jqgrid


    【解决方案1】:

    这将使他们按照您需要的方式进行排序:

    ;WITH
    CTE_All
    AS
    (
    SELECT 
        per.PersonID,
        per.FullName,
        per.PersonRow,
        ord.OrderID,
        ord.OrderName,
        ord.OrderTime,
        ord.City,
        ord.Active,
        ord.OrderRow,
        prod.ProductID,
        prod.ProductName,
        prod.ProductType,
        prod.Price,
        prod.ProductRow,
        so.Completed
    from #SubmittedOrders so
    LEFT JOIN (select *, row_number() over (order by OrderName) OrderRow from #Orders) ord 
    ON ord.OrderID = so.OrderID
    LEFT JOIN (select *, row_number() over (order by FullName) PersonRow from #Persons) per 
    ON per.PersonID = ord.PersonID
    LEFT JOIN (select *, row_number() over (order by ProductName) ProductRow from #Products) prod 
    ON prod.ProductID = so.ProductID
    )
    SELECT DISTINCT
        CONVERT(VARCHAR,PersonID) AS id, 
        0 AS level, 
        'false' AS isLeaf, 
        'null' AS parent, 
        FullName AS entity,
        '' AS OrderTime,
        '' AS City,
        '' AS Active,
        '' AS ProductType,
        '' AS Price,
        PersonRow, 
        0 AS OrderRow, 
        0 AS ProductRow
    from CTE_All Persons
    UNION ALL
    SELECT DISTINCT
        CONVERT(VARCHAR,PersonID) + '>' + CONVERT(VARCHAR,OrderID) AS id, 
        1 AS level, 
        'false' AS isLeaf, 
        CONVERT(VARCHAR,PersonID) AS parent, 
        OrderName AS entity,
        COALESCE(CAST(OrderTime AS VARCHAR(5)),'') AS OrderTime,
        City,
        Active,
        '' AS ProductType,
        '' AS Price,
        PersonRow, 
        OrderRow, 
        0 AS ProductRow
    from CTE_All Orders
    UNION ALL
    SELECT 
        CONVERT(VARCHAR,PersonID) + '>' + CONVERT(VARCHAR,OrderID) + '>' + CONVERT(VARCHAR,ProductID) AS id, 
        2 AS level, 
        'true' AS isLeaf, 
        CONVERT(VARCHAR,PersonID) + '>' + CONVERT(VARCHAR,OrderID) AS parent, 
        ProductName AS entity,
        '' AS OrderTime,
        '' AS City,
        Completed AS Active,
        ProductType,
        COALESCE(CONVERT(VARCHAR,Price),'') AS Price,
        PersonRow, 
        OrderRow, 
        ProductRow
    from CTE_All
    Order by PersonRow, OrderRow, ProductRow
    

    您可以使用创建摘要记录的组汇总来消除联合。但是你必须在你的 select 子句中添加一些 case 语句:

    select 
        CONVERT(VARCHAR,PersonID) + isnull('>' + CONVERT(VARCHAR,OrderID),'') + isnull('>' + CONVERT(VARCHAR,ProductID),'') AS id,
        Case when ProductID IS NOT null then 2 when OrderID IS NOT null then 1 else 0 end level,
        case when ProductID IS NOT null then 'true' else 'false' end isLeaf,
        case when ProductID IS NOT null then CONVERT(VARCHAR,PersonID) + isnull('>' + CONVERT(VARCHAR,OrderID),'') when OrderID IS NOT null then CONVERT(VARCHAR,PersonID) else 'null' end parent,
        COALESCE(ProductName, OrderName, FullName) entity,
        OrderTime,
        City,
        Active,
        ProductType,
        Price
    from
        (
        select #Persons.PersonID, 
            #Orders.OrderID,
            #Products.ProductID, 
            MIN(FullName) FullName,
            CASE WHEN #Orders.OrderID IS NOT NULL THEN MIN(OrderName) END OrderName,
            CASE WHEN #Products.ProductID IS NOT NULL THEN MIN(ProductName) END ProductName,
            CASE WHEN #Products.ProductID IS NOT NULL THEN MIN(convert(varchar(1),Completed)) ELSE '' END Active,
            CASE WHEN #Orders.OrderID IS NOT NULL AND #Products.ProductID IS NULL THEN MIN(OrderTime) ELSE '' END OrderTime,
            CASE WHEN #Orders.OrderID IS NOT NULL AND #Products.ProductID IS NULL THEN MIN(City) else '' END City,
            CASE WHEN #Products.ProductID IS NOT NULL THEN MIN(ProductType) ELSE '' END ProductType,
            CASE WHEN #Products.ProductID IS NOT NULL THEN convert(varchar(20),MIN(Price)) ELSE '' END Price        
        from #SubmittedOrders
        JOIN #Orders
        on #SubmittedOrders.OrderID = #Orders.OrderID
        JOIN #Persons
        on #Orders.PersonID = #Persons.PersonID
        JOIN #Products
        ON #SubmittedOrders.ProductID = #Products.ProductID
        GROUP BY ROLLUP (#Persons.PersonID, #Orders.OrderID,#Products.ProductID)
        having #Persons.PersonID is not null
        ) x
    ORDER BY FullName, OrderName, ProductName
    

    【讨论】:

    • 谢谢布赖恩。有没有比像这样将它们结合在一起更优雅的方法?
    • 我刚刚运行了您提供的代码,但它似乎添加了额外的行,因为我得到的是 27 而不是 18。
    • 我稍微更改了您的解决方案以消除重复项:对于 Person 和 Order,我将 0 分配给后续未使用的行计数,然后将 DISTINCT 添加到 SELECT
    • 对错误感到抱歉...尽管速度太快了,但我还是着急了。我还编辑了我的答案以包含一个不使用联合语句的版本。
    猜你喜欢
    • 2012-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多