2009-06-24 16 views
3

Ich habe eine Tabelle, in der ich unter anderem zwei Spalten haben, eine für das Startdatum und eine andere für das Enddatum. Ich muss eine Abfrage schreiben, die eine Spalte für jeden Monat des Jahres zurückgibt, und der Wert dieser Spalte ist 1, wenn der Monat andernfalls zwischen 0 und 0 liegt. Die PIVOT-Anweisung scheint das zu sein, wonach ich hier suche, aber von den besten kann ich sagen, dass die PIVOT-Klausel nach Werten sucht, nicht nach dem Wert zwischen zwei anderen. Ist die PIVOT-Klausel hier das richtige Konstrukt, oder muss ich 12 Case-Anweisungen aufschlüsseln und schreiben und diese dann aggregieren?SQL Pivot basierend auf Wert zwischen zwei Spalten

Antwort

2

Ich denke, ich habe die Lösung hier. Es gibt drei grundlegende Schritte:

  1. prüfen die ein Datum in jedem der 12 Monate, wenn dieser Zeitpunkt zwischen dem Start- und Enddatum ist
  2. PIVOT das Ergebnis

Um die 12 Daten, eine für jeden Monat, ich verwendete eine kleine rekursive wie WITH-Anweisung, um eine temporäre Tabelle mit 1 Spalte von 12 Daten zu erstellen:

Von hier aus kann ich CROSS JOIN diesen temporären Tisch mit der Tabelle mit den Informationen verbinden, die mir wirklich wichtig sind. Dann benutze ich WHERE date BETWEEN start AND end, um alle Einträge herauszufiltern, die nicht zu diesem Monat gehören. So etwas wie folgt aus:

SELECT other.Title, MONTH(months.date) CROSS JOIN other 
WHERE months.date BETWEEN other.start AND other.end 

In diesem Schritt werden wir nur vorsichtig sein müssen, um die Spalten SELECT wir ausdrücklich im Ergebnis wünschen, oder solche, die die PIVOT-Anweisung aggregiert werden verwenden.

Schließlich müssen wir das Ergebnis schwenken:

PIVOT (MAX(PID) FOR date IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])) 

So ist die resultierende Abfrage könnte in etwa so aussehen:

WITH months (date) AS (
SELECT GETDATE() AS date 
UNION ALL 
SELECT 
DATEADD(MONTH,1,date) 
FROM months 
WHERE DATEDIFF(MONTH,GETDATE(),date) < 12) 
SELECT Title, 
    [1]  AS January, 
    [2]  AS February, 
    [3]  AS March, 
    [4]  AS April, 
    [5]  AS May, 
    [6]  AS June, 
    [7]  AS July, 
    [8]  AS August, 
    [9]  AS September, 
    [10] AS October, 
    [11] AS November, 
    [12] AS December 
FROM 
(
SELECT other.Title,MONTH(months.date) 
CROSS JOIN other 
WHERE months.date BETWEEN other.startDate AND other.endDate 
) AS subquery 
PIVOT (MAX(PID) FOR date IN 
([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])) AS p 

Ich habe alle anderen Komplexität gezupft ich durchgemacht habe beitreten In anderen Informationen, die ich brauchte, ist dies nicht die Abfrage, die ich geschrieben habe, aber es sollte die grundlegende Abfragestruktur kapseln, die ich benutzt habe, um das Ergebnis zu erhalten, wie ich es brauchte.

0

Ich würde mit den 12 Fallaussagen gehen.

Das ist eigentlich die Lösung, die ich skizziert habe, bevor ich zurück ging und sah, dass Sie darin Ihre Frage erwähnten.

0

Warum berechnen Sie nicht eine Spalte für den Monat und verwenden Sie sie dann zum Pivotieren?

Datumsteil (Monat, [Datum])

oder habe falsch verstehe ich das Problem?

Verwandte Themen