1

私は次のデータセットを持っています:

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

3 に答える 3

2

そこにないデータを照会することはできません。したがって、参加したいすべての月をリストする(またはリストをシミュレートする)テーブルに参加する必要があります。これを行う方法は、使用しているrdbmsによって異なります。rownumを使用して、月に変換できるリストを生成するのが一般的なアプローチです。または、Postgresにはシリーズを生成する機能があります。余談ですが、メインクエリにフィルタを追加するのではなく、副選択が列句にある理由がよくわかりません。

参照:

group-byで範囲をカウントし、0カウントを含めるSQL度数分布クエリ

sysdate-30とsysdate+30の間のすべての日付のリストを生成するにはどうすればよいですか?

于 2012-04-04T22:29:37.487 に答える
2

日付範囲でグループ化するための一般的なクエリは次のとおりです。@startDateと@endDateは範囲を定義します。ユーザーのmin(created)とmax(created)、または固定範囲を設定できます。

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

これがテスト用のSQLフィドルです

于 2012-04-04T23:05:59.120 に答える
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
于 2012-04-04T23:03:27.843 に答える