2012-04-04 6 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 

をそして、私は数ヶ月のために与えられたユーザのためだけでなく、0でCOUNTを示すレポートを必要としますそこには記録がありません。

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(created)を設定することができます。

CTE monthlyRangeは、今月の最初の月、翌月の最初の月の表を生成します。検索は後で作成されたmonthlyRangesに左結合されます。ユーザーはjoinでフィルタリングされ、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 
関連する問題