分组月份,季度,半年和年份不能正常工作

时间:2017-01-18 14:07:11

标签: sql sql-server tsql grouping

我正在使用SQL Server 2012.而且我无法解决一个小问题。

当它显示标签"半年总计" " [HalfYear]"字段为空,我想用右半年标记它。

请帮忙! 感谢

这是代码:

CREATE TABLE #tempDates (OrderDate DATETIME, SubTotal  MONEY)

INSERT INTO #tempDates VALUES('2016-01-01', 10)
INSERT INTO #tempDates VALUES('2016-01-02', 10)
INSERT INTO #tempDates VALUES('2016-02-01', 15)
INSERT INTO #tempDates VALUES('2016-02-02', 15)
INSERT INTO #tempDates VALUES('2016-03-01', 20)
INSERT INTO #tempDates VALUES('2016-03-02', 20)
INSERT INTO #tempDates VALUES('2016-04-01', 10)
INSERT INTO #tempDates VALUES('2016-04-02', 10)
INSERT INTO #tempDates VALUES('2016-05-01', 15)
INSERT INTO #tempDates VALUES('2016-05-02', 15)
INSERT INTO #tempDates VALUES('2016-06-01', 20)
INSERT INTO #tempDates VALUES('2016-06-02', 20)
INSERT INTO #tempDates VALUES('2016-07-01', 10)
INSERT INTO #tempDates VALUES('2016-07-02', 10)
INSERT INTO #tempDates VALUES('2016-08-01', 15)
INSERT INTO #tempDates VALUES('2016-08-02', 15)
INSERT INTO #tempDates VALUES('2016-09-01', 20)
INSERT INTO #tempDates VALUES('2016-09-02', 20)
INSERT INTO #tempDates VALUES('2016-10-01', 10)
INSERT INTO #tempDates VALUES('2016-10-02', 10)
INSERT INTO #tempDates VALUES('2016-11-01', 15)
INSERT INTO #tempDates VALUES('2016-11-02', 15)
INSERT INTO #tempDates VALUES('2016-12-01', 20)
INSERT INTO #tempDates VALUES('2016-12-02', 20)

SELECT   
    CASE
        --WHEN GROUPING(YEAR(OrderDate)) = 1  THEN 'Year Total'
        WHEN GROUPING(
                        CASE 
                                WHEN MONTH(OrderDate) <= 6 THEN 'H1'  
                                WHEN MONTH(OrderDate) >  6 THEN 'H2'  
                                WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) <= 2 THEN 'H1'  
                                WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) >  2 THEN 'H2'  
                        END
                    ) = 1
            THEN 'Year Total'
        WHEN GROUPING(DATENAME(QUARTER, OrderDate)) = 1  THEN 'Half Year Total'
        WHEN GROUPING(MONTH(OrderDate)) = 1 THEN 'Quarter Total'
        ELSE ''
    END AS TotalType,
    MONTH(OrderDate) AS [Month],
    DATENAME(QUARTER, OrderDate) AS [Quarter],
    CASE 
         WHEN MONTH(OrderDate) <= 6 THEN 'H1'  
         WHEN MONTH(OrderDate) >  6 THEN 'H2'  
         WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) <= 2 THEN 'H1'  
         WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) >  2 THEN 'H2'  
         --WHEN DATENAME(QUARTER, OrderDate) IS NULL THEN 'Half Total' 
    END  AS [HalfYear],
    YEAR(OrderDate) AS [Year],
    SUM(SubTotal) as Purchases 
FROM     #tempDates
GROUP BY GROUPING SETS
(
    (
    MONTH(OrderDate),  
    DATENAME(QUARTER, OrderDate),
     CASE 
         WHEN MONTH(OrderDate) <= 6 THEN 'H1'  
         WHEN MONTH(OrderDate) >  6 THEN 'H2'  
         WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) <= 2 THEN 'H1'  
         WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) >  2 THEN 'H2' 
     END, 
     YEAR(OrderDate)
 ),
( 
     DATENAME(QUARTER, OrderDate),
     CASE 
         WHEN MONTH(OrderDate) <= 6 THEN 'H1'  
         WHEN MONTH(OrderDate) >  6 THEN 'H2'  
         WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) <= 2 THEN 'H1'  
         WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) >  2 THEN 'H2'  
     END,  
     YEAR(OrderDate)
 ),
 ( 
     CASE 
         WHEN MONTH(OrderDate) <= 6 THEN 'H1'  
         WHEN MONTH(OrderDate) >  6 THEN 'H2'  
         WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) <= 2 THEN 'H1'  
         WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) >  2 THEN 'H2' 
     END,  
     YEAR(OrderDate)
 ),
(Year(OrderDate))
)
ORDER BY 
       CASE 
       -- Month
       WHEN 
        GROUPING(MONTH(OrderDate)) = 1 AND 
        GROUPING(DATENAME(QUARTER, OrderDate)) = 1 AND  
        GROUPING( CASE 
                    WHEN MONTH(OrderDate) <= 6 THEN 'H1'  
                    WHEN MONTH(OrderDate) >  6 THEN 'H2'  
                    WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) <= 2 THEN 'H1'  
                    WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) >  2 THEN 'H2'  
                 END) = 1 AND 
        GROUPING(YEAR(OrderDate)) = 1 THEN '4'
       -- Quarter   
       WHEN 
        GROUPING(MONTH(OrderDate)) = 0 AND 
        GROUPING(DATENAME(QUARTER, OrderDate)) = 1 AND  
        GROUPING( CASE 
                     WHEN MONTH(OrderDate) <= 6 THEN 'H1'  
                     WHEN MONTH(OrderDate) >  6 THEN 'H2'  
                     WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) <= 2 THEN 'H1'  
                     WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) >  2 THEN 'H2'  
                 END) = 1 AND 
        GROUPING(YEAR(OrderDate)) = 1 THEN '3'
       -- Half a year
       WHEN 
        GROUPING(MONTH(OrderDate)) = 0 AND 
        GROUPING(DATENAME(QUARTER, OrderDate)) = 0 AND  
        GROUPING( CASE 
                     WHEN MONTH(OrderDate) <= 6 THEN 'H1'  
                     WHEN MONTH(OrderDate) >  6 THEN 'H2'  
                     WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) <= 2 THEN 'H1'  
                     WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) >  2 THEN 'H2'
                 END) = 1 AND 
        GROUPING(YEAR(OrderDate)) = 1 THEN '3'
      -- Year
      WHEN 
        GROUPING(MONTH(OrderDate)) = 0 AND 
        GROUPING(DATENAME(QUARTER, OrderDate)) = 0 AND  
        GROUPING( CASE 
                     WHEN MONTH(OrderDate) <= 6 THEN 'H1'  
                     WHEN MONTH(OrderDate) >  6 THEN 'H2'  
                     WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) <= 2 THEN 'H1'  
                     WHEN MONTH(OrderDate) IS NULL AND  DATENAME(QUARTER, OrderDate) >  2 THEN 'H2' 
                 END) = 0 AND 
        GROUPING(YEAR(OrderDate)) = 1 THEN '1'

      ELSE
       '0'
    END

2 个答案:

答案 0 :(得分:1)

使用WITH(CTE)预先计算半年,它解决了一次又一次输入案例statemnt,它似乎清除了故障 - 你也可以使用子查询(查询查询)

CREATE TABLE #tempDates (OrderDate DATETIME, SubTotal  MONEY)

INSERT INTO #tempDates VALUES('2016-01-01', 10)
INSERT INTO #tempDates VALUES('2016-01-02', 10)
INSERT INTO #tempDates VALUES('2016-02-01', 15)
INSERT INTO #tempDates VALUES('2016-02-02', 15)
INSERT INTO #tempDates VALUES('2016-03-01', 20)
INSERT INTO #tempDates VALUES('2016-03-02', 20)
INSERT INTO #tempDates VALUES('2016-04-01', 10)
INSERT INTO #tempDates VALUES('2016-04-02', 10)
INSERT INTO #tempDates VALUES('2016-05-01', 15)
INSERT INTO #tempDates VALUES('2016-05-02', 15)
INSERT INTO #tempDates VALUES('2016-06-01', 20)
INSERT INTO #tempDates VALUES('2016-06-02', 20)
INSERT INTO #tempDates VALUES('2016-07-01', 10)
INSERT INTO #tempDates VALUES('2016-07-02', 10)
INSERT INTO #tempDates VALUES('2016-08-01', 15)
INSERT INTO #tempDates VALUES('2016-08-02', 15)
INSERT INTO #tempDates VALUES('2016-09-01', 20)
INSERT INTO #tempDates VALUES('2016-09-02', 20)
INSERT INTO #tempDates VALUES('2016-10-01', 10)
INSERT INTO #tempDates VALUES('2016-10-02', 10)
INSERT INTO #tempDates VALUES('2016-11-01', 15)
INSERT INTO #tempDates VALUES('2016-11-02', 15)
INSERT INTO #tempDates VALUES('2016-12-01', 20)
INSERT INTO #tempDates VALUES('2016-12-02', 20)

;WITH CTE AS (select *,CASE 
                                WHEN MONTH(OrderDate) <= 6 THEN 'H1'  
                                WHEN MONTH(OrderDate) >  6 THEN 'H2'  
                        END as HY FROM  #tempDates)

SELECT   
    CASE
        --WHEN GROUPING(YEAR(OrderDate)) = 1  THEN 'Year Total'
        WHEN GROUPING(
                        hy
                    ) = 1
            THEN 'Year Total'
        WHEN GROUPING(DATENAME(QUARTER, OrderDate)) = 1  THEN 'Half Year Total'
        WHEN GROUPING(MONTH(OrderDate)) = 1 THEN 'Quarter Total'
        ELSE ''
    END AS TotalType,
    MONTH(OrderDate) AS [Month],
    DATENAME(QUARTER, OrderDate) AS [Quarter],
    hy  AS [HalfYear],
    YEAR(OrderDate) AS [Year],
    SUM(SubTotal) as Purchases 
FROM     CTE
GROUP BY GROUPING SETS
(
    (
    MONTH(OrderDate),  
    DATENAME(QUARTER, OrderDate),
     HY, 
     YEAR(OrderDate)
 ),
( 
     DATENAME(QUARTER, OrderDate),
     HY,  
     YEAR(OrderDate)
 ),
 ( 
     hy,  
     YEAR(OrderDate)
 ),
(Year(OrderDate))
)
ORDER BY 
       CASE 
       -- Month
       WHEN 
        GROUPING(MONTH(OrderDate)) = 1 AND 
        GROUPING(DATENAME(QUARTER, OrderDate)) = 1 AND  
        GROUPING( hy) = 1 AND 
        GROUPING(YEAR(OrderDate)) = 1 THEN '4'
       -- Quarter   
       WHEN 
        GROUPING(MONTH(OrderDate)) = 0 AND 
        GROUPING(DATENAME(QUARTER, OrderDate)) = 1 AND  
        GROUPING( hy) = 1 AND 
        GROUPING(YEAR(OrderDate)) = 1 THEN '3'
       -- Half a year
       WHEN 
        GROUPING(MONTH(OrderDate)) = 0 AND 
        GROUPING(DATENAME(QUARTER, OrderDate)) = 0 AND  
        GROUPING(hy) = 1 AND 
        GROUPING(YEAR(OrderDate)) = 1 THEN '3'
      -- Year
      WHEN 
        GROUPING(MONTH(OrderDate)) = 0 AND 
        GROUPING(DATENAME(QUARTER, OrderDate)) = 0 AND  
        GROUPING( hy) = 0 AND 
        GROUPING(YEAR(OrderDate)) = 1 THEN '1'

      ELSE
       '0'
    END



    drop table #tempdates;

答案 1 :(得分:0)

以下看起来似乎有点清洁了。我们只使用ad-hoc映射表

Select TotalType = max(TotalType)
      ,Month     = max(case when TotalType='' then B.R1 else null end)
      ,Quarter   = case when max(TotalType)='Year Total' then null else max(datepart(QQ,OrderDate)) end
      ,HalfYear  = max(HalfYear)
      ,Year      = max(year(OrderDate))
      ,[SubTotal] = sum([SubTotal])
 From  #tempDates A
 Join  (Values (1,1,1,'H1',''),
               (2,2,2,'H1',''),
               (3,3,3,'H1',''),
               (4,1,3,'H1','Quarter Total'),
               (5,4,4,'H1',''),
               (6,5,5,'H1',''),
               (7,6,6,'H1',''),
               (8,4,6,'H1','Quarter Total'),
               (9,1,6,'H1','Half Year Total'),
               (10,7,7,'H2',''),
               (11,8,8,'H2',''),
               (12,9,9,'H2',''),
               (13,7,9,'H2','Quarter Total'),
               (14,10,10,'H2',''),
               (15,11,11,'H2',''),
               (16,12,12,'H2',''),
               (17,9,12,'H2','Quarter Total'),
               (18,7,12,'H2','Half Year Total'),
               (19,1,12,null,'Year Total')
       ) B (Seq,R1,R2,HalfYear,TotalType)
  on  Month(OrderDate) between R1 and R2
 Group By Year(OrderDate),B.Seq
 Order By Year(OrderDate),B.Seq

返回

enter image description here