相对较新的SQL,我对这个小问题感到困惑。这似乎并不是很难做到,但我似乎无法弄明白。
我正在尝试从表中获取交易数量,但我似乎无法让sql让我显示所有月份,而不仅仅是交易发生的月份和年份。
以下是查询:
SELECT YEAR(dbo.countproject.trans_date) AS [TransYear]
, MONTH (dbo.countproject.trans_date) AS [TransMonth]
, COUNT(Id) AS TransNum
FROM dbo.countproject
WHERE dbo.countproject.make_name = 'Honda'
AND dbo.countproject.model_name = 'Civic'
AND dbo.countproject.type = 'Sale'
AND dbo.countproject.trans_type LIKE '%%EU'
AND dbo.countproject.mfr = '2000'
GROUP BY YEAR(dbo.countproject.trans_date)
, MONTH(dbo.countproject.trans_date)
ORDER BY YEAR(dbo.countproject.trans_date)
查询返回以下结果集:
| TransYear | TransMonth | TransNum |
|-----------|------------|----------|
| 2004 | 1 | 5 |
| 2004 | 3 | 1 |
| 2005 | 4 | 2 |
等等....
即使值为NULL,我也试图让它显示所有月份和年份。
我尝试创建一个新表,将年份和月份作为列以使其以某种方式加入,但我迷失了。
任何帮助将不胜感激。
答案 0 :(得分:3)
如果您使用的是SQL Server 2005 or above
,则可以使用Common Table Expressions (CTE)
来获得所需的结果。下面的示例显示了如何按照问题中的描述获取结果。
Click here to view the demo in SQL Fiddle.
描述:
SELECT
上方的UNION ALL
会获取表格中可用的最小和最大日期 dbo.countproject alltransactions
将此CTE输出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
答案 1 :(得分:0)
答案 2 :(得分:0)
唉,SQL语句只能返回表中的数据。如果您想要所有月份,您需要一张表格,其中包含您感兴趣的年/月组合,或者最好是包含所有日期和相关信息的日历表。
使用日历表,您的查询有一个from子句,如下所示:
from
(
select distinct year(date) as yr, month(date) as mon
from calendar c
where date between <earliest> and <latest>
) c
left outer join CountTable ct
on c.yr = year(ct.trans_date)
and c.mon = month(ct.trans_date)