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

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, 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)

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


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

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

1

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


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 -


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;

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;

-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

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;
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.