使用交叉应用将列转置为行

时间:2019-03-11 11:36:42

标签: sql sql-server cross-apply

Ori数据

completion handler

我想要的结果

+--------+-------+---------------+------------+--------+--------------+-------+
| RowNum | SeqNo |     Name      | NameReason | Gender | GenderReason |  ID   |
+--------+-------+---------------+------------+--------+--------------+-------+
|      1 | A123  | IronMan       |            | P      |              | E8888 |
|      2 | A123  | CaptainMarvel | A          | L      | A            | E8888 |
|      3 | A123  | Yoooo         |            |        |              | E8888 |
|      4 | A123  | Heyyy         |            |        |              | E8888 |
|      1 | B456  | Hey           |            |        |              | D2222 |
|      2 | B456  | DOTS          | A          |        |              | D2222 |
|      1 | C1234 | Hulk          |            |        |              | E8989 |
|      2 | C1234 | Cap           |            |        |              | E8989 |
|      3 | C1234 | Hat           |            |        |              | E8989 |
+--------+-------+---------------+------------+--------+--------------+-------+

查询:

+-------+-------+---------+---------------+----------+--------+
| SeqNo |  ID   | ColName |  From_Value   | To_Value | Reason |
+-------+-------+---------+---------------+----------+--------+
| A123  | E8888 | Name    | CaptainMarvel | IronMan  | A      |
| A123  | E8888 | Gender  | L             | P        | A      |
| B456  | D2222 | Name    | DOTS          | Hey      | A      |
| C1234 | E8989 | Name    | Cap           | Hulk     |        |
+-------+-------+---------+---------------+----------+--------+

注意:要查找更改。 RowNum = 1是最新更新(To_Value),RowNum = 2(From_Value)。 Rownum已经过滤掉了最上面更新的结果(行号()超过了(分区)。我只需要rownum = 2(from_Value),rownum = 1(to_value)其他人会忽略,因为1个应用程序可以更新100次,因此只需找到最新的更改即可。

从上面的查询中,如何修改所需的结果?为什么要添加from_value和to_value?

我要处理10mils +记录,20 +列,因此无法对其进行硬编码。

1 个答案:

答案 0 :(得分:0)

您可以像使用UNION一样编写查询。

  select t1.SeqNo, 
       t1.Name, 
       t1.ID, 
       'Name'                  as ColName, 
       (select name 
        from   mytable mt 
        where  mt.SeqNo = t1.seqNo 
               and RowNum = 2) as From_Value, 
       t1.Name                 as To_Value 
from   mytable t1 
where  t1.RowNum = 1 
union all
select * 
from   (select t1.SeqNo, 
               t1.Name, 
               t1.ID, 
               'Gender'                as ColName, 
               t1.Gender               as From_Value, 
               (select Gender 
                from   mytable mt 
                where  mt.SeqNo = t1.seqNo 
                       and RowNum = 1) as To_Value 
        from   mytable t1 
        where  t1.RowNum = 2) t 
where  From_Value is not null 

Online Demo

输出

+-------+---------------+-------+---------+---------------+----------+
| SeqNo | Name          | ID    | ColName | From_Value    | To_Value |
+-------+---------------+-------+---------+---------------+----------+
| A123  | CaptainMarvel | E8888 | Gender  | L             | P       |
+-------+---------------+-------+---------+---------------+----------+
| A123  | IronMan       | E8888 | Name    | CaptainMarvel | IronMan  |
+-------+---------------+-------+---------+---------------+----------+
| B456  | Hey           | D2222 | Name    | DOTS          | Hey      |
+-------+---------------+-------+---------+---------------+----------+