Jak grupować według miesięcy od pola Data przy użyciu sql

88

Jak mogę grupować tylko według miesięcy z pola daty (a nie grupować według dni)?

Oto jak wygląda moje pole daty:

2012-05-01

Oto mój obecny SQL:

select  Closing_Date, Category,  COUNT(Status)TotalCount from  MyTable
where Closing_Date >= '2012-02-01' and Closing_Date <= '2012-12-31'
and Defect_Status1 is not null
group by  Closing_Date, Category
user1858332
źródło

Odpowiedzi:

113

Użyłbym tego:

SELECT  Closing_Date = DATEADD(MONTH, DATEDIFF(MONTH, 0, Closing_Date), 0), 
        Category,  
        COUNT(Status) TotalCount 
FROM    MyTable
WHERE   Closing_Date >= '2012-02-01' 
AND     Closing_Date <= '2012-12-31'
AND     Defect_Status1 IS NOT NULL
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Closing_Date), 0), Category;

To będzie grupowane do pierwszego dnia każdego miesiąca, więc

`DATEADD(MONTH, DATEDIFF(MONTH, 0, '20130128'), 0)` 

da '20130101'. Generalnie wolę tę metodę, ponieważ zachowuje daty jako daty.

Alternatywnie możesz użyć czegoś takiego:

SELECT  Closing_Year = DATEPART(YEAR, Closing_Date),
        Closing_Month = DATEPART(MONTH, Closing_Date),
        Category,  
        COUNT(Status) TotalCount 
FROM    MyTable
WHERE   Closing_Date >= '2012-02-01' 
AND     Closing_Date <= '2012-12-31'
AND     Defect_Status1 IS NOT NULL
GROUP BY DATEPART(YEAR, Closing_Date), DATEPART(MONTH, Closing_Date), Category;

To naprawdę zależy od pożądanego wyniku. (W tym przykładzie rok zamknięcia nie jest konieczny, ale jeśli zakres dat przekracza granicę roku, może tak być).

GarethD
źródło
GarethD, dzięki stary, obie metody działały dobrze. Czy jest sposób, aby zgrupować rok i miesiąc w jednym polu? Znaczenie wyświetlania w tym formacie: 12 grudnia (grudzień to miesiąc, a 12 to rok). dzięki
user1858332
Pierwsza metoda to zrobi, wystarczy sformatować kolumnę. Radziłbym to zrobić poza SQL, ale jeśli trzeba to zrobić jako takie, możesz użyć czegoś takiegoSELECT STUFF(SUBSTRING(CONVERT(VARCHAR, CURRENT_TIMESTAMP, 6), 4, 6), 4, 1, '-');
GarethD
@GarethD Czy mógłbyś wyjaśnić, w jaki sposób po prostu użyłeś daty od 0 do daty. 0 nie jest datą.
irfandar
1
a także co robi Closing_Date = DATEADD (MONTH, DATEDIFF (MONTH, 0, Closing_Date), 0) dlaczego nie tylko DATEADD (MONTH, DATEDIFF (MONTH, 0, Closing_Date), 0)
irfandar
3
@irfandar 0 nie jest datą, ale SQL-Server niejawnie konwertuje ją na 1 stycznia 1900. Drugie pytanie Closing_Date =dotyczy tylko aliasu kolumny, jest to to samo, co AS Closing_Datepo wyrażeniu. Jest to całkowicie subiektywne, ale osobiście uważam, że alias =notacja jest znacznie łatwiejsza do odczytania niż AS Alias. Aby dowiedzieć się więcej o tym, dlaczego wolę, przeczytaj artykuł Aarona Bertranda.
GarethD
42

Użyj funkcji DATEPART, aby wyodrębnić miesiąc z daty.

Więc zrobiłbyś coś takiego:

SELECT DATEPART(month, Closing_Date) AS Closing_Month, COUNT(Status) AS TotalCount
FROM t
GROUP BY DATEPART(month, Closing_Date)
Bogdan Gavril MSFT
źródło
16
W przypadku Mysql możesz użyć MONTH () lub MONTHNAME () zamiast DATEPART
frazras
Jeśli często uruchamiasz to zapytanie, rozważ zbudowanie odpowiedniego indeksu.
użytkownik_0
Plus 1 za prostą odpowiedź.
berdem
10
Oznaczałoby to, że miesiące z różnych lat są takie same - co zwykle NIE było oczekiwane.
ivan_pozdeev
Wstawia
15

W tym celu użyłem funkcji FORMAT :

select
 FORMAT(Closing_Date, 'yyyy_MM') AS Closing_Month
 , count(*) cc 
FROM
 MyTable
WHERE
 Defect_Status1 IS NOT NULL
 AND Closing_Date >= '2011-12-01'
 AND Closing_Date < '2016-07-01' 
GROUP BY FORMAT(Closing_Date, 'yyyy_MM')
ORDER BY Closing_Month
Andrei Sura
źródło
9

Dodając MONTH(date_column)w GROUP BY.

SELECT Closing_Date, Category,  COUNT(Status)TotalCount
FROM   MyTable
WHERE  Closing_Date >= '2012-02-01' AND Closing_Date <= '2012-12-31'
AND    Defect_Status1 IS NOT NULL
GROUP BY MONTH(Closing_Date), Category
Aniket Warey
źródło
1

Funkcja DATEPART nie działa w MySQL 5.6, zamiast tego użyj MIESIĄCA („2018-01-01”)

Jordania
źródło
1

Spróbuj tego:

select min(closing_date), date_part('month',closing_date) || '-' || date_part('year',closing_date) AS month,
Category, COUNT(Status)TotalCount 
FROM MyTable
where Closing_Date >= '2012-02-01' AND Closing_Date <= '2012-12-31'
AND Defect_Status1 is not null
GROUP BY month, Category,
ORDER BY 1

W ten sposób grupujesz według połączonego formatu daty, połączonego znakiem -

John Sonnino
źródło
0
SELECT  to_char(Closing_Date,'MM'), 
        Category,  
        COUNT(Status) TotalCount 
FROM    MyTable
WHERE   Closing_Date >= '2012-02-01' 
AND     Closing_Date <= '2012-12-31'
AND     Defect_Status1 IS NOT NULL
GROUP BY Category;
Nida
źródło
0

Wersja SQL Server 2012 powyżej,

SELECT  format(Closing_Date,'yyyy-MM') as ClosingMonth,
        Category,  
        COUNT(Status) TotalCount 
FROM    MyTable
WHERE   Closing_Date >= '2012-02-01' 
AND     Closing_Date <= '2012-12-31'
AND     Defect_Status1 IS NOT NULL
GROUP BY format(Closing_Date,'yyyy-MM'), Category;
YHTAN
źródło
-1

Możesz to zrobić za pomocą Year (), Month () Day () i datepart ().

W twoim przykładzie byłoby to:

select  Closing_Date, Category,  COUNT(Status)TotalCount from  MyTable
where Closing_Date >= '2012-02-01' and Closing_Date <= '2012-12-31' 
and Defect_Status1 is not null 
group by Year(Closing_Date), Month(Closing_Date), Category
user1845584
źródło
To nie jest poprawny SQL
Mad Echet
Jest to poprawne, ale przynosi nieprzewidywalne wyniki, ponieważ nie grupujesz według wybranych pól. Możesz mieć dowolną wartość w dacie zamknięcia, o ile data i rok są takie same.
Mad Echet
-1

Wypróbuj następujący kod

SELECT  Closing_Date = DATEADD(MONTH, DATEDIFF(MONTH, 0, Closing_Date), 0), 
        Category,  
        COUNT(Status) TotalCount 
FROM    MyTable
WHERE   Closing_Date >= '2012-02-01' 
AND     Closing_Date <= '2012-12-31'
AND     Defect_Status1 IS NOT NULL
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Closing_Date), 0), Category;
Antony raj
źródło