用SQL给经过两次转置的结果集添加列标题

Posted wzy0623

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用SQL给经过两次转置的结果集添加列标题相关的知识,希望对你有一定的参考价值。

问题:

        想合并两个结果集,并将它们转置为两列,另外还想给各组添加列“标题”。

表数据:

mysql> select * from t1;
+------+------------+
| a    | b          |
+------+------------+
|  100 | HOPKINS    |
|  100 | JONES      |
|  100 | TONEY      |
|  200 | MORALES    |
|  200 | P.WHITAKER |
|  200 | MARCIANO   |
|  200 | ROBINSON   |
|  300 | LACY       |
|  300 | WRIGHT     |
|  300 | J.TAYLOR   |
+------+------------+
10 rows in set (0.00 sec)

mysql> select * from t2;
+------+------------+
| a    | b          |
+------+------------+
|  400 | CORRALES   |
|  400 | MAYWEATHER |
|  400 | CASTILLO   |
|  400 | MARQUEZ    |
|  400 | MOSLEY     |
|  500 | GATTI      |
|  500 | CALZAGHE   |
|  600 | LAMOTTA    |
|  600 | HAGLER     |
|  600 | HEARNS     |
|  600 | FRAZIER    |
|  700 | GUINN      |
|  700 | JUDAH      |
|  700 | MARGARITO  |
+------+------------+
14 rows in set (0.00 sec)

要求结果集:

+-------------+-------------+
| research    | apps        |
+-------------+-------------+
| 100         | 400         |
|  HOPKINS    |  CORRALES   |
|  JONES      |  MAYWEATHER |
|  TONEY      |  CASTILLO   |
| 200         |  MARQUEZ    |
|  MORALES    |  MOSLEY     |
|  P.WHITAKER | 500         |
|  MARCIANO   |  GATTI      |
|  ROBINSON   |  CALZAGHE   |
| 300         | 600         |
|  LACY       |  LAMOTTA    |
|  WRIGHT     |  HAGLER     |
|  J.TAYLOR   |  HEARNS     |
|             |  FRAZIER    |
|             | 700         |
|             |  GUINN      |
|             |  JUDAH      |
|             |  MARGARITO  |
+-------------+-------------+

实现:

select max(case when flag2 = 0 then it_dept else '' end) research,   -- 行转列
       max(case when flag2 = 1 then it_dept else '' end) apps
  from (
select sum(flag1) over (partition by flag2 order by flag1,rn) flag,it_dept, flag2 -- 每个分区取行号
  from ( 
select flag1,flag2, it_dept, row_number() over(order by flag2, a,id desc,rn) rn  -- 排序显示
  from (
select 1 flag1, 0 flag2, case id when 2 then a else concat(' ',b)  end it_dept,a,id,rn   -- 标题行替换
  from (select x.*, y.id, row_number()over(partition by x.a order by y.id) rn   -- rn用于where条件
          from (select a, b, count(*)over(partition by a) cnt   -- 每个分区的行数
                  from t1) x,
               (select 1 id union select 2) y) t    -- 笛卡尔积制造2倍的行数
 where rn <= cnt+1   -- 每个分区多出一行

union all

select 1 flag1, 1 flag2, case id when 2 then a else concat(' ',b)  end it_dept,a,id,rn
  from (select x.*, y.id, row_number()over(partition by x.a order by y.id) rn
          from (select a, b, count(*)over(partition by a) cnt
                  from t2) x,
               (select 1 id union select 2) y) t 
 where rn <= cnt+1  
) t) t ) t 
-- 按行号分组max,合并行
group by flag;

以上是关于用SQL给经过两次转置的结果集添加列标题的主要内容,如果未能解决你的问题,请参考以下文章

用SQL对经过排名的结果集进行转置

用SQL对经过排名的结果集进行转置

sql server多重行列转置的优化

ClickHouse 按列输出,而不是按行输出(实际上没有转置的转置?)

使用数据透视/转置的 SQL Server

在 SQL 中将行转置为列标题