sql-server - 枢轴和级联空列

标签 sql-server sql-server-2008 pivot

我有一个包含特定月份值的表:

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

结果

|日期 |因素 | XFACTOR |
---------------------------------
| 2013-01-01 | 1 | 1 |
| 2013-02-01 | (空) | 1 |
| 2013-03-01 | (空) | 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 | (空) | 1 |
| 2013-09-01 | (空) | 1 |
| 2013-10-01 | (空) | 1 |
| 2013-11-01 | (空) | 1 |
| 2013-12-01 | (空) | 1 |

SQL Fiddle

最佳答案

不知道您是否需要日历表中的日期是动态的,或者是否需要 mfg可以超过 5,但这应该会给你一些想法。

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

关于sql-server - 枢轴和级联空列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14837962/

相关文章:

sql - 对带有多个点的 varchar 列进行排序。点赞数

sql - 需要一些有关 Sql Server 和简单触发器的帮助

laravel - (Laravel) 通过数据透视表的多态关系

sql - 使用 UTF-8 SQL Server 整理 SQL_Latin1_General_CP850_BIN2 时出错

sql - 链接服务器上的身份插入失败

asp.net - asp.net 中 SP 的估计成本

xml - 如何将包含多列的行转换为包含两列(字段名和值)和多行的表?

sql - 在 SQL Server 2008 中只存储月份和年份?

sql - 根据另一个表中的列值选择一个表中的行?

Pandas - Pivot/stack/unstack/melt