Задача Tsql месяц - PullRequest
       0

Задача Tsql месяц

1 голос
/ 01 апреля 2011

У меня есть таблица как:

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 извлекается из значения datetime. в реальном мире мне придется показать предыдущие 12 месяцев с прошлого месяца в порядке DESC! какие-либо предложения для этого?

Ответы [ 3 ]

5 голосов
/ 01 апреля 2011

Попробуйте создать справочную таблицу месяцев и 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.

2 голосов
/ 01 апреля 2011

Пример таблицы

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) преобразует дату в формат «ДД МММ ГГ», нам нужна только MMM YY часть
  2. В SELECT мы дополнительно извлекаем из него только трехзначный месяц, используя LEFT (, 3)
  3. Подзапрос L содержит одну запись и столбец PVT, который является первой датой последнего месяца
  4. Ряд чисел 0-11 используется для создания значений месяцев за последние 12 месяцев по формуле dateadd(month,-M.N,L.PVT)
  5. Диапазон t.dt >= .. and t.dt < .. находит данные за один месяц
1 голос
/ 01 апреля 2011

Как насчет этого?Результат содержит месяц и год, но вы можете вырезать его как хотите.

;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 и измените комментарий к стоимости, чтобы получить старое решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...