2017-01-18 4 views
0

Ich benutze SQL Server 2012. Und ich bin nicht in der Lage, ein kleines Problem zu lösen.Gruppierung mit Monat, Quartal, Halbjahr und Jahr funktioniert nicht richtig

Wenn das Tag "Half Year Total" angezeigt wird, ist das Feld "[HalfYear]" null und ich möchte es mit der rechten Hälfte des Jahres beschriften.

Jede Hilfe bitte! Dank

Dies ist der Code:

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 
+0

Warum sind Sie nicht einen Kalender Tabelle/Datumsdimension verwenden? [Erstellen einer Datumstabelle/Dimension in SQL Server 2008 - David Stein] (http://www.made2mentor.com/2011/06/creating-a-date-tableddimension-for-sql-server-2008/) und - [ Erstellen einer Datumsdimension oder einer Kalendertabelle in SQL Server - Aaron Bertrand] (https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/) – SqlZim

+0

Entschuldigung, ich weiß das nicht und ich kenne Dimensionen nicht sehr gut. Brauche ich es, um mein Problem zu lösen? Die Abfrage hat nur ein sehr kleines Problem, zumindest sieht es so aus ... – MarcosF8

Antwort

1

Verwendung MIT (CTE) bis vor das Halbjahr zu berechnen, löst sie den Fall statemnt immer wieder eintritt, und es scheint, die Panne zu löschen - Sie könnten auch eine Unterabfrage verwenden (abfragen, um eine Abfrage)

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; 
+0

es funktioniert sehr gut. Ich werde dieses Ergebnis niemals selbst erreichen. Du bist unglaublich! Danke vielmals ! – MarcosF8

+0

@ MarcosF8 - danke – Cato

0

Die folgende scheint ein wenig sauberer in meinem Kopf. Wir verwenden nur eine Ad-hoc-Zuordnungstabelle

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 

Returns

enter image description here