【问题标题】:Adding column to pivot query in SQL Server在 SQL Server 中将列添加到透视查询
【发布时间】:2016-11-09 01:12:07
【问题描述】:

我有以下疑问:

select 
    msisdn, value, date 
from 
    tang
where 
    date > dateadd(mm, -6, getdate())
    and value > 0

使用一些数据,例如:

msisdn      value   date
772102730   1.0000  2016-01-07 08:48:30.540
772125566   2.0000  2016-01-07 10:01:50.753
772108924   1.0000  2016-01-07 10:04:27.940
772136349   5.0000  2016-01-07 10:08:07.183
772127823   1.0000  2016-01-07 10:08:19.773
774521923   1.0000  2016-01-07 10:10:13.927

以及以下枢轴查询:

select msisdn,r1,r2,r3
from 
(
    select *
    from 
    (
        select msisdn, value, 'r'+convert(varchar(4),rank() over (partition by msisdn order by date asc)) as r
        from tang
        where date > dateadd(mm,-6,getdate())
        and value > 0 
    ) a
    where r < 'r4' 
 ) a
pivot 
(
        min(value)
        for r in (r1,r2,r3)
) p

使用以下数据:

msisdn      r1      r2      r3
701048594   1.0000  2.0000  2.0000
720000810   2.0000  NULL    NULL
720030474   2.0000  2.0000  NULL
720049121   4.5000  2.0000  3.0000
720187431   2.0000  2.0000  2.0000
720189845   3.0000  NULL    NULL
720201300   5.0000  NULL    NULL
720229335   2.0000  NULL    NULL
720458626   2.0000  2.0000  2.0000
720512511   2.0000  5.0000  2.5000

我想添加如下数据列:

msisdn  r1  r2  r3 d1  d2  d3

其中d1是r1的数据,d2是r2的数据,d3是r3的数据

怎么做?

【问题讨论】:

  • d1 is the data of r1 等是什么意思?你的意思是日期列中的那个值?
  • pivot 运算符的 mssql 实现非常有限。我建议您返回使用基于等级和 group by 子句的派生表和 case 表达式。 max (case when r =1 then column end)
  • 抱歉造成混淆,数据表示 r1 的日期等。见第一张表。

标签: sql sql-server pivot


【解决方案1】:

我已经通过以下查询解决了这个问题:
select a.msisdn, r1, r2, r3, r1_date, r2_date, r3_date from ( select msisdn,r1,r2,r3 from ( select * from ( select msisdn, value, ''r''+convert(varchar(4),rank() over (partition by msisdn order by date asc)) as r from tang where date > dateadd(mm,-6,getdate()) and value > 0 ) a where r < ''r4'' ) a pivot ( min(value) for r in (r1,r2,r3) ) p ) a join ( select msisdn,r1_date,r2_date,r3_date from ( select * from ( select msisdn, date, ''r''+convert(varchar(4),rank() over (partition by msisdn order by date asc))+''_date'' as r from tang where date > dateadd(mm,-6,getdate()) and value > 0 ) a where r < ''r4_date'' ) a pivot ( min(date) for r in (r1_date,r2_date,r3_date) ) p ) b on a.msisdn = b.msisdn

【讨论】:

    【解决方案2】:

    使用此查询可能会获得更好的性能,而不是组合 2 个透视查询。

    SELECT  msisdn,
            MIN(CASE WHEN r = 1 THEN value END) AS r1,
            MIN(CASE WHEN r = 2 THEN value END) AS r2,
            MIN(CASE WHEN r = 3 THEN value END) AS r3,
            MIN(CASE WHEN r = 4 THEN value END) AS r4,
            MIN(CASE WHEN r = 1 THEN date END) AS d1,
            MIN(CASE WHEN r = 2 THEN date END) AS d2,
            MIN(CASE WHEN r = 3 THEN date END) AS d3,
            MIN(CASE WHEN r = 4 THEN date END) AS d4
    FROM    (SELECT msisdn,
                    value,
                    RANK() OVER (PARTITION BY msisdn ORDER BY date ASC) AS r
             FROM   tang
             WHERE  date > DATEADD(mm,-6,GETDATE())
                    AND value > 0
            ) a
    WHERE r < 4
    GROUP BY msisdn
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-06
      • 1970-01-01
      • 1970-01-01
      • 2012-11-13
      • 1970-01-01
      • 2014-12-31
      • 2019-05-08
      相关资源
      最近更新 更多