特殊的行转列需求

mysql> select * from ddd;
+------+------+------+------+
| stat | yi   | er   | san  |
+------+------+------+------+
| a    |    1 |    2 |    3 |
| a    |    4 |    5 |    6 |
| b    |   11 |   22 |    3 |
| b    |    5 |   61 |   82 |
+------+------+------+------+
4 rows in set (0.00 sec)

把上面的数据行转列,结果如下

+------+------+------+------+------+------+------+------+------+------+
| stat | c1   | c2   | c3   | c4   | c5   | c6   | c7   | c8   | c9   |
+------+------+------+------+------+------+------+------+------+------+
| a    |    1 |    2 |    3 |    4 |    5 |    6 | NULL | NULL | NULL |
| b    |    3 |    5 |   11 |   22 |   61 |   82 | NULL | NULL | NULL |
+------+------+------+------+------+------+------+------+------+------+
2 rows in set (0.01 sec)

这种需求在oracle中比较容易实现,因为oracle中有row_number可以生成序号。mysql中就只有另找方法了

set @rn=0;
set @stat='';
select stat,
max(case when rn = 1 then yi end) as c1,
max(case when rn = 2 then yi end) as c2,
max(case when rn = 3 then yi end) as c3,
max(case when rn = 4 then yi end) as c4,
max(case when rn = 5 then yi end) as c5,
max(case when rn = 6 then yi end) as c6,
max(case when rn = 7 then yi end) as c7,
max(case when rn = 8 then yi end) as c8,
max(case when rn = 9 then yi end) as c9
from
(
SELECT stat,
       yi,
       IF(@stat = stat, @rn := @rn + 1, @rn := 1) AS rn,
       @stat := stat AS last_stat
from
(
select stat,yi from ddd
union all
select stat,er from ddd
union all
select stat,san from ddd
) as a
order by stat,yi
) as a
group by stat;

通过分组生成的序号来定位,就可以把对应的值转到相应位置了

mysql> set @rn=0;
Query OK, 0 rows affected (0.00 sec)

mysql> set @stat='';
Query OK, 0 rows affected (0.00 sec)

mysql> select stat,
    -> max(case when rn = 1 then yi end) as c1,
    -> max(case when rn = 2 then yi end) as c2,
    -> max(case when rn = 3 then yi end) as c3,
    -> max(case when rn = 4 then yi end) as c4,
    -> max(case when rn = 5 then yi end) as c5,
    -> max(case when rn = 6 then yi end) as c6,
    -> max(case when rn = 7 then yi end) as c7,
    -> max(case when rn = 8 then yi end) as c8,
    -> max(case when rn = 9 then yi end) as c9
    -> from
    -> (
    -> SELECT stat,
    ->        yi,
    ->        IF(@stat = stat, @rn := @rn + 1, @rn := 1) AS rn,
    ->        @stat := stat AS last_stat
    -> from
    -> (
    -> select stat,yi from ddd
    -> union all
    -> select stat,er from ddd
    -> union all
    -> select stat,san from ddd
    -> ) as a
    -> order by stat,yi
    -> ) as a
    -> group by stat;
+------+------+------+------+------+------+------+------+------+------+
| stat | c1   | c2   | c3   | c4   | c5   | c6   | c7   | c8   | c9   |
+------+------+------+------+------+------+------+------+------+------+
| a    |    1 |    2 |    3 |    4 |    5 |    6 | NULL | NULL | NULL |
| b    |    3 |    5 |   11 |   22 |   61 |   82 | NULL | NULL | NULL |
+------+------+------+------+------+------+------+------+------+------+
2 rows in set (0.01 sec)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值