2012-04-04 3 views
0

SQL의 COUNT와 GROUP BY 나는 다음과 같은 데이터 세트가 있습니다특정 달 없음 기록의 달

ID | CREATED  | USER 
-------------------------- 
1 | 2012-01-14 | XYZ 
2 | 2012-03-14 | XYZ 
3 | 2012-03-15 | XYZ 
4 | 2012-03-24 | ABC 
5 | 2012-04-10 | XYZ 
6 | 2012-04-11 | ABC 

를 그리고 지정된 사용자에 대한뿐만 아니라 함께 COUNT를 보여주는 보고서가 필요 개월 0 거기에 기록이 없습니다.

MTH | COUNT 
------------- 
JAN | 1 
FEB | 0 
MAR | 2 
APR | 1 

레코드가없는 달은 0이지만 작동하지는 못했습니다. 지금까지 오류가 발생하는 구문이 있습니다.

SELECT Month(CREATED), COUNT(SELECT * FROM SEARCHES WHERE USER = 'XYZ') 
FROM SEARCHES 
GROUP BY Month(CREATED) 

답변

1

하는 것은 다음 날짜 범위로 그룹화의 일반적인 쿼리입니다. @startDate와 @endDate는 범위를 정의합니다. 사용자 또는 일부 고정 범위에 대해 min (만든) 및 max (만든)를 설정할 수 있습니다.

CTE monthlyRange는 이번 달의 첫 번째 달, 다음 달 첫 달을 생성합니다. 검색은 나중에 만들어져서 monthlyRanges에 왼쪽으로 결합됩니다. 사용자는 조인에서 필터링됩니다.이 조인과 필터링은 where 절에서 효과적으로 필터링하여 내부 조인으로 바꿀 수 있습니다.

declare @startDate datetime 
declare @endDate datetime 
set @startDate = '2012-01-01' 
set @endDate = '2013-01-01' 

; with monthlyRange (startMonth, startNextMonth) as (
    select dateadd (m, datediff (m, 0, @startDate), 0), 
     dateadd (m, datediff (m, 0, @startDate) + 1, 0) 
    union all 
    select dateadd (m, 1, startMonth), 
     dateadd (m, 1, startNextMonth) 
    from monthlyRange 
    where startNextMonth <= dateadd (m, datediff (m, 0, @endDate), 0) 
) 
SELECT Year(monthlyRange.startMonth) Year, 
     Month(monthlyRange.startMonth) Month, 
     COUNT(searches.Created) Count 
    FROM monthlyRange 
    left join SEARCHES 
    on monthlyRange.startMonth <= Searches.Created 
    and monthlyRange.startNextMonth > Searches.Created 
    and [USER] = 'XYZ' 
GROUP BY Year(monthlyRange.startMonth), Month(monthlyRange.startMonth) 
order by 1, 2 

Here is Sql Fiddle for testing

+0

이 큰 일! SQL 피들을 소개해 주셔서 감사합니다. – greener

2

거기에없는 데이터는 쿼리 할 수 ​​없습니다. 따라서 가입하려는 모든 달을 나열하거나 나열하는 테이블에 가입해야합니다. 이를 수행하는 방법은 사용중인 rdbms에 따라 달라질 수 있습니다. rownum을 사용하여 개월로 변환 할 수있는 목록을 생성하는 것이 일반적인 방법입니다. 또는 Postgres에는 시리즈를 생성하는 함수가 있습니다. 제쳐두고, 하위 쿼리가 기본 쿼리에 필터를 추가하는 대신 열 절에 왜 있는지 이해할 수 없습니다.

은 참조 :

SQL frequency distribution query to count ranges with group-by and include 0 counts

How to generate list of all dates between sysdate-30 and sysdate+30?

0

이 시도 :

CREATE TABLE #DaTable(
    ID INT, 
    CREATED DATE, 
    USER_ VARCHAR(10) 
) 
INSERT INTO #DaTable(ID, CREATED, USER_) VALUES 
(1 , '2012-01-14', 'XYZ'), 
(2 , '2012-03-14' , 'XYZ'), 
(3 , '2012-03-15' , 'XYZ'), 
(4 , '2012-03-24' , 'ABC'), 
(5 , '2012-04-10' , 'XYZ'), 
(6 , '2012-04-11' , 'ABC') 

CREATE TABLE #DaMonths(
    Nr INT, 
    Name VARCHAR(10) 
) 
INSERT INTO #DaMonths(Nr, Name) VALUES 
(1, 'Jan'), 
(2, 'Feb'), 
(3, 'Mar'), 
(4, 'Apr'), 
(5, 'May'), 
(6, 'Jun'), 
(7, 'Jul'), 
(8, 'Aug'), 
(9, 'Sep'), 
(10, 'Oct'), 
(11, 'Nov'), 
(12, 'Dec') 

SELECT M.Nr, M.Name, COUNT(DT.ID) as Count_ 
FROM #DaMonths as M 
    LEFT OUTER JOIN #DaTable as DT ON 
    M.Nr = Month(DT.CREATED) 
GROUP BY M.Nr, M.Name 
ORDER BY M.Nr