Ret*_*der 2 t-sql sql-server sql-server-2000
在SQL Server 2000中,我需要在客户订单的临时表中列出年份,月份作为整数.
如果月份不存在,我仍然需要列出年,月,0.00美元.
在SQL Server 2000中执行此操作的最佳方法是什么?
01/01/2010
到07/01/2010
会产生:
__Year__, __Month__ , __Billed__
2010,1,$5000.00
2010,2,$6000.00
2010,3,$8000.00
2010,4,$0.00
2010,5,$4000.00
2010,6,$4500.00
Run Code Online (Sandbox Code Playgroud)
使用此代码:
select grp.* from
(
select year(orderdate) as yr,
month(orderdate) as mn,
sum(billed)
from Orders
group by year(orderdate), month(orderdate), billed
) grp
order grp.yr, grp.mn
Run Code Online (Sandbox Code Playgroud)
是否有一个简单的解决方案,可以不跳过没有结算的月份并添加0.00美元?
2005年以上(抱歉,我错过了2000年的要求):
DECLARE @Orders TABLE(OrderDate DATETIME, billed INT);
INSERT @Orders SELECT '20100104', 500
UNION SELECT '20100106', 700;
DECLARE
@year INT,
@end_month TINYINT;
SELECT
@year = 2010,
@end_month = 7;
WITH s(n) AS
(
SELECT TOP (@end_month) ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.objects ORDER BY [object_id]
),
m(s) AS
(
SELECT DATEADD(MONTH, n-1, DATEADD(YEAR, @year-1900, 0))
FROM s
)
SELECT
[Year] = @year,
[Month] = MONTH(m.s),
Billed = COALESCE(SUM(t.billed), 0)
FROM m
LEFT OUTER JOIN @Orders AS t
ON t.OrderDate >= m.s
AND t.OrderDate < DATEADD(MONTH, 1, m.s)
GROUP BY
MONTH(m.s)
ORDER BY [Year], [Month];
Run Code Online (Sandbox Code Playgroud)
对于2000年,它只是略有不同:
CREATE TABLE #Orders(OrderDate DATETIME, billed INT);
INSERT #Orders SELECT '20100104', 500
UNION SELECT '20100106', 700;
DECLARE
@year INT,
@end_month TINYINT;
SELECT
@year = 2010,
@end_month = 7;
SELECT
[year] = @year,
[month] = MONTH(m.s),
billed = COALESCE(SUM(t.billed), 0)
FROM
(
SELECT s = DATEADD(MONTH, n-1, DATEADD(YEAR, @year-1900, 0)) FROM
(
SELECT DISTINCT TOP 12 n = number
FROM master..spt_values
WHERE number BETWEEN 1 AND @end_month
ORDER BY number
)
AS s
) AS m
LEFT OUTER JOIN #Orders AS t
ON t.OrderDate >= m.s
AND t.OrderDate < DATEADD(MONTH, 1, m.s)
GROUP BY MONTH(m.s);
Run Code Online (Sandbox Code Playgroud)
现在可以肯定的是,我没有2000个实例可以方便地进行测试 - 这只是袖手旁观.