Как группировать по месяцам из поля даты с помощью sql


87

Как я могу группировать только по месяцам из поля даты (а не по дням)?

Вот как выглядит мое поле даты:

2012-05-01

Вот мой текущий 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

Ответы:


112

Я бы использовал это:

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;

Это будет группироваться до первого числа каждого месяца, поэтому

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

даст '20130101'. Я обычно предпочитаю этот метод, поскольку он сохраняет даты как даты.

В качестве альтернативы вы можете использовать что-то вроде этого:

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;

Это действительно зависит от вашего желаемого результата. (Год закрытия не является обязательным в вашем примере, но если диапазон дат пересекает границу года, это может быть).


GarethD, спасибо, оба метода работали нормально. Есть ли способ сгруппировать год и месяц в одном поле? Значение отображается в таком формате: Dec-12 (Dec - месяц, а 12 - год). спасибо
user1858332

Первый способ сделает это, вам просто нужно отформатировать столбец. Я бы посоветовал сделать это вне SQL, но если это нужно сделать как таковое, вы можете использовать что-то вродеSELECT STUFF(SUBSTRING(CONVERT(VARCHAR, CURRENT_TIMESTAMP, 6), 4, 6), 4, 1, '-');
GarethD

@GarethD Не могли бы вы объяснить, как вы просто использовали dateiff между 0 и date. 0 это не свидание.
irfandar

1
а также то, что Closing_Date = DATEADD (MONTH, DATEDIFF (MONTH, 0, Closing_Date), 0) делает, почему не просто DATEADD (MONTH, DATEDIFF (MONTH, 0, Closing_Date), 0)
irfandar

3
@irfandar 0 - это не дата, но SQL-Server неявно преобразует ее в 1 января 1900 года. Второй вопрос Closing_Date =- это просто псевдоним столбца, он такой же, как AS Closing_Dateпосле выражения. Это полностью субъективно, но я лично считаю, что alias =обозначения легче читать, чем AS Alias. Подробнее о том, почему я предпочитаю его, читайте в статье Аарона Бертрана.
GarethD

42

Используйте функцию DATEPART, чтобы извлечь месяц из числа.

Итак, вы бы сделали что-то вроде этого:

SELECT DATEPART(month, Closing_Date) AS Closing_Month, COUNT(Status) AS TotalCount
FROM t
GROUP BY DATEPART(month, Closing_Date)

16
Для Mysql вы можете использовать MONTH () или MONTHNAME () вместо DATEPART
frazras

Если вы часто выполняете этот запрос, подумайте о создании соответствующего индекса.
user_0 02

Плюс 1 за простой ответ.
berdem

10
При этом месяцы разных лет будут считаться одинаковыми, чего обычно НЕ ожидалось.
ivan_pozdeev

Это ставит "1" для января и т. Д. Оно не сообщает вам название месяца
user890332

15

Для этого я использовал функцию 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

Путем добавления MONTH(date_column)в 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

Попробуй это:

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

Таким образом, вы группируете по объединенному формату даты, к которому присоединяется -


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

Версия SQL Server 2012 выше,

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

Вы можете сделать это с помощью Year (), Month () Day () и datepart ().

В вашем примере это будет:

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

Это недопустимый SQL
Mad Echet

Что ж, это действительно так, но дает непредсказуемые результаты, поскольку вы не группируете по выбранным полям. Вы можете иметь любое значение в дате закрытия, если дата и год совпадают.
Mad Echet 05

-1

Попробуйте следующий код

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;
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.