如果您使用SQL Server 2005 or above,您可以使用Common Table Expressions (CTE) 来获得所需的结果。下面的示例显示了如何获取问题中描述的结果。
Click here to view the demo in SQL Fiddle.
说明:
- 创建和插入语句创建表并填充一些示例数据。我已根据问题中提供的查询创建了表。
- WITH 子句中的语句正在执行递归表达式。在这种情况下,
UNION ALL 上方的 SELECT 获取表 dbo.countproject 中可用的最小和最大日期
- 获取最小日期后,UNION ALL 之后的第二个 SELECT 语句会以 1 个月的间隔递增日期,直到递归表达式达到表中可用的最大日期。
- 递归 CTE 已生成所有可能的可用日期。此输出在名为 alltransactions 的表中可用。
- 我们必须使用
LEFT OUTER JOIN 将此 CTE 输出 alltransactions 与实际表 countproject 连接起来,因为即使没有交易,我们也希望显示所有年份和月份。
-
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