如何按行和列分组?

时间:2013-04-23 09:10:32

标签: sql tsql reporting-services sql-server-2008-r2 grouping

我找不到任何可以帮助我接近目标的问题/答案。我有下表check code on SQL Fiddle

SITENAME RTYPE SEASON  CTRSTAT  CTRTYPE UNITS  STARTDATE  WKTYPE    INVSTAT
 site1    T2B    P     null      null    92      null     FRSA_P    Unsold
 site1    T2B    Pre   null      null    36      null     FRSA_P    Unsold
 site1    T2B    PRI   null      null    173     null     FRSA_P    Unsold
 site1    T2B    SPE   null      null    56      null     FRSA_P    Unsold
 site1    T2B    P    Complete   FRSA    2     2013-01-01 FRSA_P    Sold
 site1    T2B    Pre  Complete   FRSA    2     2013-01-01 FRSA_P    Sold
 site1    T2B    PRI  Complete   FRSA    2     2013-01-01 FRSA_P    Sold
 site1    T2B    P    Complete   FRSA    1     2013-03-05 FRSA_P    Sold
 site1    T2B    P    Complete   FRSA    3     2014-01-01 FRSA_P    Sold
 site1    T2B    Pre  Complete   FRSA    4     2014-01-01 FRSA_P    Sold
 site1    T3B    P     null      null    69      null     FRSA_P    Unsold
 site1    T3B    Pre   null      null    26      null     FRSA_P    Unsold
 site1    T3B    PRI   null      null    125     null     FRSA_P    Unsold
 site1    T3B    SPE   null      null    40      null     FRSA_P    Unsold
 site1    T3B    Pre  Complete   FRSA    2     2013-01-01 FRSA_P    Sold
 site1    T3B    P    Complete   FRSA    1     2014-01-01 FRSA_P    Sold
 site1    T3B    Pre  Complete   FRSA    2     2014-01-01 FRSA_P    Sold

然后以某种方式得到如下图所示的报告。如果InvStatus未售出,则报告应返回未售出,否则返回CTRSTAT。

Result after grouping by columns and rows with totals

请不要注意总计和总计,图像来自使用其他数据的Excel。只是要得到所需结果的样本。

编辑:日期列对应一整年,例如,2013-03-05列属于01/01/2013列。如果是空日期,则它们将显示在显示的最后一年,在这种情况下01/01/2014,但可以是2015年o在最后显示的任何时间段。

我尝试了几种不同的方法,使用GROUP BY以及各种类型的GROUPINGSETS,但都没有效果。 CUBEROLLUP没用,或者至少我没有设法得到正确的结果。也许只是不可能,至少不是一个简单的方法。

以下是我尝试过的众多查询之一的示例,尝试将其扭曲以获得类似报告的内容,但仍然没有任何结果。

SELECT
       sitename, rtype, season, ctrstat, ctrtype, SUM(units)
      ,startdate, invstat
  FROM tt
 GROUP BY
GROUPING SETS ((sitename,InvStat,ctrstat)
               ,(RType,ctrtype,season,startdate)
               ,()
              )

编辑:也许应该更好地使用SSRS执行此任务?

2 个答案:

答案 0 :(得分:2)

正如你在编辑中提到的那样,我认为这样做我的SSRS是要走的路。您可以使用矩阵轻松创建您要查找的报告。通过使用SQL小提示中提供的数据,您可以快速获得如下所示的内容。

编辑:添加总值 enter image description here

enter image description here

答案 1 :(得分:1)

虽然SSRS可能是更好的选择,但这里是如何使用SQL查询完成的。最后,将两者结合起来可能是最好的解决方案。

WITH CTE_Pivot AS 
(
    SELECT
         sitename
        ,rtype
        ,season
        ,CASE WHEN invstat = 'Sold' AND ctrStat = 'Complete' AND YEAR(startdate)=2013 THEN units ELSE 0 END AS Complete2013
        ,CASE WHEN invstat = 'Sold' AND ctrStat = 'Complete' AND (YEAR(startdate)=2014 OR startdate IS NULL) THEN units ELSE 0 END AS Complete2014
        ,CASE WHEN invstat = 'Unsold' AND YEAR(startdate)=2013 THEN units ELSE 0 END AS Unsold2013
        ,CASE WHEN invstat = 'Unsold' AND (YEAR(startdate)=2014 OR startdate IS NULL) THEN units ELSE 0 END AS Unsold2014
        ,units AS Total
    FROM tt 
)
SELECT sitename,rtype,season
    ,SUM(Complete2013) AS Complete2013
    ,SUM(Complete2014) AS Complete2014
    ,SUM(Unsold2013) AS Unsold2013
    ,SUM(Unsold2014) AS Unsold2014
    ,SUM(Total) AS GrandTotal
FROM CTE_Pivot
GROUP BY GROUPING SETS ((sitename,rtype,season),(sitename,rtype),sitename)

<强> SQLFiddle DEMO

第一部分是转动你的专栏。这是一种相当简单的方法,不使用PIVOT函数,而是在CASE语句中为每列声明条件。它假设您有可能不完美的固定数量的可能值(和列),但创建dynamic columns require dynamic SQL会使此查询达到全新的复杂程度。

毕竟在这种情况下,我真的不认为你对CTRSTAT会有很多不同的值,我想你早先知道所有可能的值。岁月有点问题,但我猜不会有那么多。您可以选择“今年,上一年,下一年”,以使其更适应未来。

查询的第二部分只是使用简单的分组集进行分组。 ROLLUP与此相同。

相关问题