I have a table that holds values for particular months:
| MFG | DATE | FACTOR | ----------------------------- | 1 | 2013-01-01 | 1 | | 2 | 2013-01-01 | 0.8 | | 2 | 2013-02-01 | 1 | | 2 | 2013-12-01 | 1.55 | | 3 | 2013-01-01 | 1 | | 3 | 2013-04-01 | 1.3 | | 3 | 2013-05-01 | 1.2 | | 3 | 2013-06-01 | 1.1 | | 3 | 2013-07-01 | 1 | | 4 | 2013-01-01 | 0.9 | | 4 | 2013-02-01 | 1 | | 4 | 2013-12-01 | 1.8 | | 5 | 2013-01-01 | 1.4 | | 5 | 2013-02-01 | 1 | | 5 | 2013-10-01 | 1.3 | | 5 | 2013-11-01 | 1.2 | | 5 | 2013-12-01 | 1.5 |
What I would like to do is pivot these using a calendar
table (already defined):
And finally, cascade the NULL
columns to use the previous value.
What I've got so far is a query that will populate the NULL
s with the last value for mfg = 3
. Each mfg
will always have a value for the first of the year. My question is; how do I pivot this and extend to all mfg
?
SELECT c.[date],
f.[factor],
Isnull(f.[factor], (SELECT TOP 1 factor
FROM factors
WHERE [date] < c.[date]
AND [factor] IS NOT NULL
AND mfg = 3
ORDER BY [date] DESC)) AS xFactor
FROM (SELECT [date]
FROM calendar
WHERE Datepart(yy, [date]) = 2013
AND Datepart(d, [date]) = 1) c
LEFT JOIN (SELECT [date],
[factor]
FROM factors
WHERE mfg = 3) f
ON f.[date] = c.[date]
Result
| DATE | FACTOR | XFACTOR | --------------------------------- | 2013-01-01 | 1 | 1 | | 2013-02-01 | (null) | 1 | | 2013-03-01 | (null) | 1 | | 2013-04-01 | 1.3 | 1.3 | | 2013-05-01 | 1.2 | 1.2 | | 2013-06-01 | 1.1 | 1.1 | | 2013-07-01 | 1 | 1 | | 2013-08-01 | (null) | 1 | | 2013-09-01 | (null) | 1 | | 2013-10-01 | (null) | 1 | | 2013-11-01 | (null) | 1 | | 2013-12-01 | (null) | 1 |
Don't know if you need the dates to be dynamic from the calender table or if mfg
can be more than 5 but this should give you some ideas.
select *
from (
select c.date,
t.mfg,
(
select top 1 f.factor
from factors as f
where f.date <= c.date and
f.mfg = t.mfg and
f.factor is not null
order by f.date desc
) as factor
from calendar as c
cross apply(values(1),(2),(3),(4),(5)) as t(mfg)
) as t
pivot (
max(t.factor) for t.date in ([20130101], [20130201], [20130301],
[20130401], [20130501], [20130601],
[20130701], [20130801], [20130901],
[20131001], [20131101], [20131201])
) as P
SQL Fiddle
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With