【问题标题】:To calculate the percentage of items for various item types using SQL Server 2012使用 SQL Server 2012 计算各种项目类型的项目百分比
【发布时间】:2013-07-10 04:50:45
【问题描述】:

我的表如下

ITEM_CREATION_DATE  ITEM_ID ITEM_TYPEID ITEM_FOLDER
2008-04-04 00:00:00.000 ITEM01  12  Y
2008-12-14 00:00:00.000 ITEM04  13  Y
2008-09-24 00:00:00.000 ITEM01  13  Y
2009-12-04 00:00:00.000 ITEM01  12  NULL
2009-04-09 00:00:00.000 ITEM02  13  NULL
2010-08-13 00:00:00.000 ITEM01  13  Y
2010-01-28 00:00:00.000 ITEM02  14  Y
2011-04-09 00:00:00.000 ITEM03  13  NULL
2011-10-19 00:00:00.000 ITEM01  12  NULL
2011-04-29 00:00:00.000 ITEM04  13  NULL
2011-02-19 00:00:00.000 ITEM01  13  NULL
2011-04-09 00:00:00.000 ITEM03  13  NULL
2012-02-29 00:00:00.000 ITEM01  14  Y
2012-12-09 00:00:00.000 ITEM03  14  Y
2012-07-19 00:00:00.000 ITEM01  14  Y
2012-06-29 00:00:00.000 ITEM01  12  Y
2012-04-29 00:00:00.000 ITEM03  NULL    Y
2012-04-19 00:00:00.000 ITEM03  NULL    Y
2013-04-09 00:00:00.000 ITEM01  13  Y
2013-09-14 00:00:00.000 ITEM01  13  Y
2013-05-24 00:00:00.000 ITEM01  12  Y
2013-01-09 00:00:00.000 ITEM01  12  Y
2013-11-09 00:00:00.000 ITEM01  14  Y
2013-09-21 00:00:00.000 ITEM01  12  Y
2013-07-09 00:00:00.000 ITEM02  14  Y
2013-08-09 00:00:00.000 ITEM02  NULL    Y
2013-09-09 00:00:00.000 ITEM02  NULL    Y

我需要获取各种项目类型中项目的百分比。这里的挑战是在单个查询中完成相同的任务。

我需要如下结果

Year     12     13      14  NULL
2008    33.33%      66.66%      0.00%   0.00%
2009    0.00%       0.00%       0.00%   0.00%
2010    0.00%       50%     50% 0.00%
2011    0.00%       0.00%       0.00%   0.00%
2012    16.66%      0.00%       50% 33.33%
2013    33.33%      22.22%      22.22%  22.22%

解决此查询的最佳方法是 Pivot,所以我从这个方向开始。 我对这些类型的查询非常陌生,所以我需要各位专家的帮助。

我设法获取了包含各种项目类型的项目计数的查询

select *  from 
(
SELECT  YEAR(ITEM_CREATION_DATE) AS [Year], ITEM_ID, ITEM_TYPEID FROM [dbo].[ITEM_DETAIL] 
WHERE ITEM_FOLDER IS NOT NULL 
) AS Result pivot (count(ITEM_ID) for ITEM_TYPEID in ([12],[13],[14])) as MyTbl

输出 12 13 14 年

2008    1       2       0
2010    0       1       1
2012    1       0       3
2013    3       2       2

但这里的问题是我错过了剩下的年份(即 2009 年和 2011 年),因为它们不属于 where 子句(ITEM_FOLDER IS NOT NULL) 我需要表格中的所有年份。

我的查询中也未获取 NULL 项目类型。

请告诉我是否有解决此问题的正确方法。它可以通过存储过程中的多个 SQL 轻松完成。但就我而言,这不是一个可行的解决方案。我需要执行一个 SQL 查询来获得所需的输出

看起来如果使用 PIVOT,我只能获得计数或百分比,但不能同时获得两者。 如果 Year 为 NULL 并且 ITEM_TYPE 为 NULL,我是否可以考虑这样的事情 2008 12 1 33.33% 2008 13 2 66.66% 2009 12 1 50.00% 2009 13 1 50.00% 2010 13 1 50.00% 2010 14 1 50.00% 2011 12 1 20.00% 2011 13 4 80.00% 2012 无 2 33.33% 2012 12 1 16.66% 2012 14 3 50.00% 2013 无 2 22.22% 2013 12 3 33.33% 2013 13 2 22.22% 2013 14 2 22.22% 输出不对。 对于 ITEM_FOLDER 为 null 的年份,所有项目类型的计数必须为 0 如果一年内只有一个项目类型的记录,则需要将其余所有项目类型的计数显示为 0 。 像下面这个 YEAR ITEM_TYPE COUNT PERCENTAGE 2008 12 1 33.33 2008 13 2 66.67 2008 14 0 0.00 2009 12 0 0.00 2009 13 0 0.00 2009 14 0 0.00 2010 12 0 0.00 2010 13 1 50.00 2010 14 1 50.00 2011 12 0 0.00 2011 13 0 0.00 2011 14 0 0.00 2012 空 2 33.33 2012 12 1 16.67 2012 13 0 0.00 2012 14 3 50.00 2013 空 2 22.22 2013 12 3 33.33 2013 13 2 22.22 2013 14 2 22.22

【问题讨论】:

    标签: sql-server-2008 tsql reporting-services cube rollup


    【解决方案1】:

    试试这个

    SELECT [Year],[12],[13],[14],[0] AS [NULL]  FROM 
    (
        SELECT  YEAR(ITEM_CREATION_DATE) AS [Year]
        , CASE WHEN ITEM_FOLDER IS NOT NULL THEN ITEM_ID ELSE NULL END AS [ITEM_ID]
        , ISNULL(ITEM_TYPEID,0) AS ITEM_TYPEID FROM ITEM_DETAIL
    ) AS Result 
    PIVOT 
    (
        COUNT(ITEM_ID) for ITEM_TYPEID in ([12],[13],[14],[0])
    ) as MyTbl
    

    DEMO HERE

    编辑

    查看下面的百分比

    SELECT [Year]
        ,Convert(DECIMAL(8,2), [12]*100/Convert(DECIMAL(8,2),Total)) AS [12]
        ,Convert(DECIMAL(8,2), [13]*100/Convert(DECIMAL(8,2),Total)) AS [13]
        ,Convert(DECIMAL(8,2), [14]*100/Convert(DECIMAL(8,2),Total)) AS [14]
        ,Convert(DECIMAL(8,2), [NULL]*100/Convert(DECIMAL(8,2),Total)) AS [NULL] 
    FROM
    (
        SELECT [Year],[12],[13],[14],[0] AS [NULL],
        (SELECT COUNT(ITEM_ID) FROM #ITEM_DETAIL WHERE YEAR(ITEM_CREATION_DATE) = MyTbl.[Year] GROUP BY YEAR(ITEM_CREATION_DATE)) AS Total 
        FROM 
        (
            SELECT  YEAR(ITEM_CREATION_DATE) AS [Year]
            , CASE WHEN ITEM_FOLDER IS NOT NULL THEN ITEM_ID ELSE NULL END AS [ITEM_ID]
            , ISNULL(ITEM_TYPEID,0) AS ITEM_TYPEID FROM ITEM_DETAIL
        ) AS Result 
        PIVOT 
        (
            COUNT(ITEM_ID) for ITEM_TYPEID in ([12],[13],[14],[0])
        ) as MyTbl
    ) T
    

    PERCENTAGE DEMO

    编辑 2

    SELECT 
        [YEAR]
        ,ITEM_TYPEID
        ,CNT
        ,CONVERT(DECIMAL(8,2),CNT*100/CONVERT(DECIMAL(8,2),TOTAL)) AS PERCENTAGE 
    FROM
    (
        SELECT [YEAR],ITEM_TYPEID,SUM(CNT) AS CNT
        ,(SELECT COUNT(1) FROM #ITEM_DETAIL T1 WHERE YEAR(T1.ITEM_CREATION_DATE)=T.[YEAR]
             GROUP BY YEAR(ITEM_CREATION_DATE)) AS [TOTAL]
        FROM
        (
            SELECT  YEAR(ITEM_CREATION_DATE) AS [YEAR]
             , ISNULL(ITEM_TYPEID,'NULL') AS ITEM_TYPEID 
             , 1 AS CNT
            FROM #ITEM_DETAIL  
        ) T
        GROUP BY [YEAR],ITEM_TYPEID
    ) T1
    ORDER BY [YEAR]
    

    PERCENTAGE DEMO 2

    SELECT [Year],C.itemtype,C.cnt,C.percentage FROM
    (
        SELECT [Year],[12]
            ,Convert(DECIMAL(8,2), [12]*100/Convert(DECIMAL(8,2),Total)) AS [12p],[13]
            ,Convert(DECIMAL(8,2), [13]*100/Convert(DECIMAL(8,2),Total)) AS [13p],[14]
            ,Convert(DECIMAL(8,2), [14]*100/Convert(DECIMAL(8,2),Total)) AS [14p],[NULLv] 
            ,Convert(DECIMAL(8,2), [NULLv]*100/Convert(DECIMAL(8,2),Total)) AS [NULLp] 
        FROM
        (
            SELECT [Year],[12],[13],[14],[0] AS [NULLv],
            (SELECT COUNT(ITEM_ID) FROM #ITEM_DETAIL WHERE YEAR(ITEM_CREATION_DATE) = MyTbl.[Year] GROUP BY YEAR(ITEM_CREATION_DATE)) AS Total 
            FROM 
            (
                SELECT  YEAR(ITEM_CREATION_DATE) AS [Year]
                , CASE WHEN ITEM_FOLDER IS NOT NULL THEN ITEM_ID ELSE NULL END AS [ITEM_ID]
                , ISNULL(ITEM_TYPEID,0) AS ITEM_TYPEID FROM #ITEM_DETAIL
            ) AS Result 
            PIVOT 
            (
                COUNT(ITEM_ID) for ITEM_TYPEID in ([12],[13],[14],[0])
            ) as MyTbl
        ) T
    ) P
    CROSS APPLY
    (
        VALUES
        ('12',[12],[12p]),
        ('13',[13],[13p]),
        ('14',[14],[14p]),
        ('NULL',NULLv,[NULLp])
    ) C(itemtype,cnt,percentage)
    WHERE C.itemtype <> 'NULL' OR C.cnt > 0 
    

    PERCENTAGE DEMO 3

    【讨论】:

    • 我需要一个查询中的计数和百分比。非常感谢。
    • 看起来如果使用 PIVOT,我只能获得计数或百分比,但不能同时获得两者。如果 Year 为 NULL 且 ITEM_TYPE 为 NULL 2008 12 1 33.33% 2008 13 2 66.66% 2009 12 1 50.00% 2009 13 1 50.00% 2010 13 1 50.00% 2010 14 1 50.00% 12 1 20.00%2011 13 4 80.00%2012 null 2 33.33%2012 2012 12 1 16.66%2012 14 3 50.00%2013 null 2 22.22%2013 2013 12 3 33.33%2013 13 2 22.22%2013 2013 14 2 22.22%22.22%
      跨度>
    • 看起来如果使用 PIVOT,我只能获得计数或百分比,但不能同时获得两者。如果 Year 为 NULL 且 ITEM_TYPE 为 NULL 2008 12 1 33.33% 2008 13 2 66.66% 2009 12 1 50.00% 2009 13 1 50.00% 2010 13 1 50.00% 2010 14 1 50.00% 12 1 20.00%2011 13 4 80.00%2012 null 2 33.33%2012 2012 12 1 16.66%2012 14 3 50.00%2013 null 2 22.22%2013 2013 12 3 33.33%2013 13 2 22.22%2013 2013 14 2 22.22%22.22%
      跨度>
    • 查询没有给出所需的输出。请在上面查看。
    猜你喜欢
    • 1970-01-01
    • 2019-11-05
    • 2020-09-15
    • 2015-10-03
    • 2018-02-17
    • 1970-01-01
    • 2011-04-07
    • 1970-01-01
    • 2021-10-15
    相关资源
    最近更新 更多