tsql月问题

时间:2011-03-31 21:54:03

标签: sql tsql sql-server-2008

我有一张表:

id   month   cost
------------------
1    Jan      200
1    Mar      204
1    May      200
1    Dec      201

我需要一个输出(按月排序,包括一年中的其他月份 - 显示所有12个月):

to   month   cost
------------------
1    Jan      200
NULL Feb      NULL
1    Mar      204
....
....
....
1    Dec      201

在TSQL中如何做到这一点的任何想法或解决方案?

谢谢!

edit :: month从日期时间值中提取。 在现实世界中,我必须在DESC订单中显示上个月的前12个月!有什么建议吗?

3 个答案:

答案 0 :(得分:5)

尝试构建一个月份参考表,然后JOIN。这是在varchar数据类型中使用数月的最快捷方式。

declare @foo table (id int, [mon] varchar(100), cost int)    
declare @mon table (mon varchar(100), orderWeight int)

INSERT INTO @mon (mon, orderWeight)
   VALUES ('Jan',1), ('Feb',2),('Mar',3),('Apr',4),('May',5),('Jun',6),('Jul',7),
          ('Aug',8),('Sep',9),('Oct',10),('Nov',11),('Dec',12)

INSERT INTO @foo(id, [mon], cost)
VALUES ( 1    ,'Jan' ,     200),
( 1    ,'Mar',      204),
( 1    ,'May' ,    200),
( 1    ,'Dec'  ,    201)

select f.id,
       m.[mon] , 
       f.cost
from @mon as m 
left join @foo as f on m.mon = f.mon
order by m.orderWeight

结果:

enter image description here

现在可以使用order by orderWeight保证您的订购。

答案 1 :(得分:2)

样本表

create table mytable(id int, dt datetime, cost money)
insert mytable values
(1,GETDATE()-10,200),
(1,GETDATE()-40,204),
(1,GETDATE()-100,200),
(1,GETDATE()-200,201);

查询,使用SQL Server 2008特定语法,并正确排序

select
    t.id [to],
    CONVERT(char(3),dateadd(month,-M.N,L.PVT),7) [Month],
    sum(t.cost) totalCost
from (select PVT=dateadd(month,datediff(month,0,getdate())-1,0)) L
cross join (values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11)) M(N)
left join mytable t
    on t.dt >= dateadd(month,-M.N,L.PVT)
   and t.dt <  dateadd(month,-M.N+1,L.PVT)
group by t.id, right(CONVERT(char(9),dt,6),6), M.N, L.PVT
order by M.N

它的作用:

  1. right(CONVERT(char(9),dt,6),6)将日期转换为“DD MMM YY”格式,我们只需要MMM YY部分
  2. 在SELECT中,我们使用LEFT(,3)
  3. 进一步从中提取3个月的月份
  4. 子查询L有一个记录和列PVT,这是上个月的第一个日期
  5. 系列号0-11用于创建过去12个月的月份值,使用公式dateadd(month,-M.N,L.PVT)
  6. 范围t.dt >= .. and t.dt < ..查找单个月的数据

答案 2 :(得分:1)

这个怎么样? 结果包含月份和年份,但您可以根据需要将其删除。

;with months
as
(
select dateadd(month, -1, dateadd(day, datediff(day, 0, getdate()), 0)) as m
union all
select dateadd(month, -1, m)
from months
where   m > dateadd(month, -12, getdate())
)

-- Testdata
,yourTable(id,somedate,cost)
as
(
    select 1, '2011-01-03', 200
    union all
    select 1, '2011-03-06', 204
    union all
    select 1, '2010-05-09', 200
    union all
    select 1, '2010-05-19', 201
    union all
    select 1, '2010-12-02', 201
)
-- end testdata

select  yt.id
        ,datename(month,coalesce(yt.somedate, m.m)) as [month]
        ,datename(year,coalesce(yt.somedate, m.m)) as [year]
        --,yt.cost
        ,sum(yt.cost) as cost
from    months m
left join yourTable yt
    on  datepart(year, yt.someDate) = DATEPART(year, m.m)
    and datepart(month, yt.someDate) = DATEPART(month, m.m)
group by
    yt.id
    ,datename(month,coalesce(yt.somedate, m.m))
    ,datename(year,coalesce(yt.somedate, m.m))
    ,m.m
order by m.m desc

编辑:改变支持总和的解决方案。 删除group by - 部分并更改成本注释,以获得旧解决方案。