用SQL语句实现行到列的转换

本文介绍了一种使用SQL对日志数据进行整理和汇总的方法,通过row_number()函数配合case表达式,实现了多行数据到一行数据的转换,便于进行数据分析。具体包括如何根据主机类型和状态筛选数据,并展示了一段具体的SQL实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<案例>

 

log表


id    host            name           content              status     date
1    web主机     cpu使用率     cpu使用率5%       正常       2009-8-6
2    web主机     内存使用率    内存使用率20%     正常        2009-8-6
3    web主机     空间使用率    空间使用率39%     正常        2009-8-6
4    业务主机      cpu使用率    cpu使用率5%       正常       2009-8-6
5    业务主机      内存使用率   内存使用率20%      正常       2009-8-6
6    业务主机      空间使用率   空间使用率39%      正常       2009-8-6
7    接口主机      cpu使用率    cpu使用率5%       正常      2009-8-6
8    接口主机      内存使用率   内存使用率20%      不正常       2009-8-6
9    接口主机      空间使用率   空间使用率39%      正常      2009-8-6

 

希望能统计处如下结果

web主机状态  cup使用率    内存使用率      业务主机状态  cup使用率     内存使用率       接口主机状态  cup使用率  内存使用率 
正常          cpu使用率5%    内存使用率20% 正常             cpu使用率5%  内存使用率20%  不正常   cpu使用率5%  内存使用率20%  

 

 

<实现方法> 

select decode(max(case when host='web主机' and status<>'正常' then status end),null,'正常','不正常')  web主机状态,
 
max(case when host='web主机' and rn=1 then content end ) cpu使用率,
 
max(case when host='web主机' and rn=2 then content end ) 内存使用率,
  decode(
max(case when host='业务主机' and status<>'正常' then status end),null,'正常','不正常')  业务主机状态,
 
max(case when host='业务主机' and rn=1 then content end)  cpu使用率,
 
max(case when host='业务主机' and rn=2 then content end) 内存使用率,
  decode(
max(case when host='接口主机' and status<>'正常' then status end),null,'正常','不正常')  接口主机状态,
 
max(case when host='接口主机' and rn=1 then content end)  cpu使用率,
 
max(case when host='接口主机' and rn=2 then content end)  内存使用率

from(
    
select row_number()over(partition by host order by id) rn,
         host,name,content,status
from log);

group by date;

 

先整理一下源数据。这里主要使用row_number()函数,将源数据依据字段host进行分组,然后再分组内部进行排序。排序生成的序号,赋值给新变量rn。

 

将多行数据整理成一行,上面的SQL语句通过select选取字段来实现。我们先看第一组,其他两组方法都是一样的。

 

第一个字段,遍历全表,挑出所有记录中host字段为“web主机”,同时判断status,有没有不等于“正常“的记录,如果有的话,该字段为”不正常“,反之,该字段等于“正常”。这里的max()函数非常重要,它使得select在选取该字段时,需要遍历每一行。

 

第二个字段,遍历全表,选择记录中host字段为“web主机”,同时rn为2的记录,将这条记录的content值赋予该字段。这里的max()也是不能或缺的,它使select需要遍历所有行,来选取符合条件的行中的字段值。

 

第三个字段,选取方法与第二个字段相同,不再重复。

 

<补充知识>

 

row_number() over (partition by col1 order by col2)
表示根据col1分组,在分组内部根据 col2排序
而这个值就表示每组内部排序后的顺序编号(组内连续的唯一的)

表内容如下:
name | seqno | description
A | 1 | test
A | 2 | test
A | 3 | test
A | 4 | test
B | 1 | test
B | 2 | test
B | 3 | test
B | 4 | test
C | 1 | test
C | 2 | test
C | 3 | test
C | 4 | test

我想有一个sql语句,搜索的结果是
A | 1 | test
A | 2 | test
B | 1 | test
B | 2 | test
C | 1 | test
C | 2 | test
实现:
select name,seqno,description
from(select name,seqno,description,row_number()over(partition by name order by seqno)id
from table_name) where id<=3;
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值