【问题标题】:Average / Sum From bottom to top of Hierarchy - SQL Server从层次结构的底部到顶部的平均值/总和 - SQL Server
【发布时间】:2017-08-05 09:07:25
【问题描述】:

我们在 SQL Server 中有 3 个表

Here is the Schema of the tables

组将具有层次结构,这些层次结构将映射到用户表中的用户。并且每个用户在事务表中都会有事务。

我们希望得到如下输出:

- Company (810)     
    - New York (810)            
        - Administration (310)
            - USER 1    100 
            - USER 2    200 
            - USER 3     10 
        - Support (500)
            - USER 4    500

    - Michigan          
        - Accounts      
    - San Diego         

任何人都可以建议使用 SQL 查询来实现这一点吗?

【问题讨论】:

  • 您没有表现出任何努力,但我建议您在表示层中处理这种类型的输出格式。
  • 请求的格式在您的描述中不清楚。请以表格格式显示所需的输出。
  • 很好奇您的 schema 有数据,但没有数据类型。还有Group_IdUser_Id,但没有Transaction_Id。请阅读this,了解一些改进问题的技巧。

标签: sql-server tsql hierarchy


【解决方案1】:

您可以使用递归 CTE 来构建组的层次结构。之后,您可以将您的用户和事务加入此层次结构。

这是一个使用您的表定义的示例:

WITH GroupHierarchy AS (
    SELECT
        GROUP_ID,
        GROUP_NAME,
        PARENT_ID,
        CONVERT(NVARCHAR(200),NULL) AS PARENT_NAME,
        0 AS HierarchyLevel
    FROM GROUPS g
    WHERE g.PARENT_ID IS NULL
    UNION ALL
    SELECT 
        g.GROUP_ID,
        g.GROUP_NAME,
        g.PARENT_ID,
        gh.GROUP_NAME AS PARENT_NAME,
        HierarchyLevel + 1 AS HierarchyLevel
    FROM GROUPS g
        INNER JOIN GroupHierarchy gh ON gh.GROUP_ID = g.PARENT_ID
)
SELECT 
    gh.PARENT_NAME,
    gh.GROUP_NAME,
    HierarchyLevel,
    [USER_NAME],
    SUM([VALUE]) AS TransactionSum,
    AVG([VALUE]) AS TransactionAvg
FROM GroupHierarchy gh
    LEFT OUTER JOIN USERS u ON u.GROUP_ID = gh.GROUP_ID
    LEFT OUTER JOIN TRANSACTIONS t on t.[USER_ID] = u.[USER_ID]
GROUP BY PARENT_NAME, GROUP_NAME, HierarchyLevel, [USER_NAME]
ORDER BY PARENT_NAME, GROUP_NAME, HierarchyLevel, [USER_NAME]

上面的查询会给你这样的输出格式:

PARENT_NAME    GROUP_NAME      HierarchyLevel USER_NAME    TransactionSum TransactionAvg
-------------- --------------  -------------- ------------ -------------- --------------
NULL           Company         0              NULL         NULL           NULL
Company        Michigan        1              User 3       44             22
Company        Michigan        1              User 4       100            100
Company        New York        1              User 1       310            103
Company        New York        1              User 2       570            190
Company        San Diego       1              User 5       54             54
Company        San Diego       1              User 6       NULL           NULL
Michigan       Accounts        2              User 9       NULL           NULL
Michigan       Finance         2              User 10      NULL           NULL
New York       Administration  2              User 7       NULL           NULL
New York       Support         2              User 8       NULL           NULL
San Diego      Sales           2              NULL         NULL           NULL
San Diego      Service         2              NULL         NULL           NULL

【讨论】:

    【解决方案2】:

    这一切现在都内置在 SQL 中。一起去:

    GROUP BY ROLLUP(PARENT_NAME, GROUP_NAME, [USER_NAME])
    

    在汇总值时,较低级别的字段将为 NULL

    查看https://technet.microsoft.com/en-us/library/ms189305(v=sql.90).aspx了解更多信息,以及如何处理源字段中的NULLs(如果适用),并美化输出中的NULLs。 (很多ISNULLs。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多