を使用している場合は、を使用して目的の結果を得るSQL Server 2005 or above
ことができます。Common Table Expressions (CTE)
以下の例は、質問で説明したように結果を取得する方法を示しています。
SQL Fiddleでデモを表示するには、ここをクリックしてください。
説明:
- Createステートメントとinsertステートメントは、テーブルを作成し、いくつかのサンプルデータを入力します。質問で提供されたクエリに基づいてテーブルを作成しました。
- WITH句内のステートメントは、再帰式を実行しています。この場合、
SELECT
上記はテーブルdbo.countprojectUNION ALL
で利用可能な最小および最大の日付をフェッチします
- 最小日付がフェッチされると、UNION ALLの後の2番目のSELECTステートメントは、再帰式がテーブルで使用可能な最大日付に達するまで、1か月間隔で日付をインクリメントします。
- 再帰CTEは、可能なすべての利用可能な日付を生成しました。この出力は、alltransactionsという名前のテーブルで利用できます。
- トランザクションがない場合でもすべての年と月を表示したいので、このCTE出力を実際のテーブルと結合する必要
alltransactions
があります。countproject
LEFT OUTER JOIN
- テーブル
alltransactions
とは、日付の年と月の部分でcountproject
結合されます。次に、クエリはWHERE句に必要なフィルタを適用し、データを年と月でグループ化してから、年と月で並べ替えます。
- サンプルデータから、表の最も早い日付がであり、最も
2004-07-01
遅い日付がであることがわかります2005-12-01
。したがって、出力は2004年/月07から2005年/月12までを示します。
お役に立てば幸いです。
スクリプト:
CREATE TABLE dbo.countproject
(
id INT NOT NULL IDENTITY
, trans_date DATETIME NOT NULL
, make_name VARCHAR(20) NOT NULL
, model_name VARCHAR(20) NOT NULL
, type VARCHAR(20) NOT NULL
, trans_type VARCHAR(20) NOT NULL
, mfr INT NOT NULL
);
INSERT INTO dbo.countproject (trans_date, make_name, model_name, type, trans_type, mfr) VALUES
('1900-01-01', 'Honda', 'Civic', 'Sale', 'EU', 2000),
('1900-01-01', 'Toyota', 'Corolla', 'Sale', 'EU', 2000),
('2004-07-01', 'Nissan', 'Altima', 'Sale', 'EU', 2000),
('2005-12-01', 'Toyota', 'Camry', 'Sale', 'EU', 2000),
('2004-04-01', 'Ford', 'Focus', 'Sale', 'EU', 2000),
('2005-08-01', 'Honda', 'Civic', 'Sale', 'EU', 2000),
('2005-11-01', 'Toyota', 'Camry', 'Sale', 'EU', 2000),
('2004-08-01', 'Toyota', 'Corolla', 'Sale', 'EU', 2000),
('2005-12-01', 'Honda', 'Civic', 'Sale', 'EU', 2000),
('2004-07-01', 'Honda', 'Civic', 'Sale', 'EU', 2000),
('2004-11-01', 'Honda', 'Civic', 'Sale', 'EU', 2000),
('2005-08-01', 'Honda', 'Civic', 'Sale', 'EU', 2000);
;WITH alltransactions
AS
(
SELECT MIN(trans_date) AS continuousdate
, MAX(trans_date) AS maximumdate
FROM dbo.countproject
WHERE trans_date <> '1900-01-01'
UNION ALL
SELECT DATEADD(MONTH, 1, continuousdate) AS continuousdate
, maximumdate
FROM alltransactions
WHERE DATEADD(MONTH, 1, continuousdate) <= maximumdate
)
SELECT YEAR(at.continuousdate) AS [Year]
, MONTH(at.continuousdate) AS [Month]
, COUNT(cp.trans_date) AS [Count]
FROM alltransactions at
LEFT OUTER JOIN countproject cp
ON YEAR(at.continuousdate) = YEAR(cp.trans_date)
AND MONTH(at.continuousdate) = MONTH(cp.trans_date)
AND cp.make_name = 'Honda'
and cp.model_name = 'Civic'
and cp.type = 'Sale'
and cp.trans_type LIKE '%EU'
and cp.mfr = '2000'
GROUP BY YEAR(at.continuousdate)
, MONTH(at.continuousdate)
ORDER BY [Year]
, [Month];
出力:
Year Month Count
----- ------ -----
2004 4 0
2004 5 0
2004 6 0
2004 7 1
2004 8 0
2004 9 0
2004 10 0
2004 11 1
2004 12 0
2005 1 0
2005 2 0
2005 3 0
2005 4 1
2005 5 0
2005 6 0
2005 7 0
2005 8 2
2005 9 0
2005 10 0
2005 11 0
2005 12 1