如何在两个日期之间显示全年,几个月的整数?

时间:2011-08-24 20:00:44

标签: sql-server tsql sql-server-2000

在SQL Server 2000中,我需要根据客户的订单列出临时表中的年份,月份。

如果月份不存在,我仍然需要列出年,月,0.00美元。

在SQL Server 2000中执行此操作的最佳方法是什么?

01/01/201007/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

使用此代码:

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

是否有一个简单的解决方案,可以不跳过没有结算的月份并添加$ 0.00?

2 个答案:

答案 0 :(得分:5)

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];

对于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);

现在我承认我没有2000个实例可以方便地进行测试 - 这只是袖手旁观。

答案 1 :(得分:3)

创建一个包含0到100,000或其他数字的数字表。

然后是这样的:

DECLARE @StartDate AS DATE
DECLARE @EndDate AS DATE

SELECT YEAR(DATEADD(m, Numbers.N, @StartDate))
    ,MONTH(DATEADD(m, Numbers.N, @StartDate))
    ,ISNULL(OrderSummary.Billed, 0) AS Billed
FROM Numbers
LEFT JOIN (
    SELECT year(orderdate), month(orderdate), sum(billed)
    FROM Orders
    GROUP by year(orderdate), month(orderdate)
) AS OrderSummary (Yr, Mn, Billed)
ON YEAR(DATEADD(m, Numbers.N, @StartDate)) = OrderSummary.Yr
    AND MONTH(DATEADD(m, Numbers.N, @StartDate)) = OrderSummary.Mn
WHERE Numbers.N < DATEDIFF(m, @StartDate, @EndDate)

2005年使用常用表格表达式稍微容易一些。