建议收藏丨sql行转列的一千种写法!!

问题

ps.哈哈哈哈,这不就是10次面试9次问的行转列嘛~

讨论过程中

大佬们纷纷谏言献策,集思广益。

二 火花

========

2.1 内置函数实现行转列

原理

SELECT *

FROM student

PIVOT (

SUM(score) FOR subject IN (语文, 数学, 英语)

) #默认按照score和subject以外其它字段进行group by

结果展示

2.2 经典case when实现

使用case when来依条件分列是最简单的一种方法。

select 学生号,

sum(case 科目 when ‘语文’ then 成绩 end) as 语文,

sum(case 科目 when ‘数学’ then 成绩 end) as 数学,

from table

where …

group by 学生号

case when进阶,动态列数行转列:

但是,转换后列数不固定的情况下呢?对照上面的例子来说就是,假设我并不知道学生学了哪些科目的时候应该怎么做?

我们继续用case when,但是由于列的不固定,需要先根据条件分支产生的可能性来拼接一下语句再动态执行。直接上码看效果可能更清晰一点:

declare @sql varchar(4000)

set @sql = ‘select 学生号’

select @sql = @sql + ‘,sum(case 科目 when ‘’’+科目+‘’’ then  成绩 end) [‘+科目+’]’

from (select distinct 科目 from table  ) as a

order by 科目

select @sql = @sql+’ from table  group by 学生号’

–print @sql

exec(@sql)

2.3 Python groupby 实现列转行

df_new = df_new.groupby(by=‘电影名’, as_index=False).agg(“/”.join)

print(df_new)

2.4 Python pandas 实现列转行

import pandas as pd

df = pd.DataFrame([[‘夏洛特烦恼’,‘沈腾/马丽/尹正/艾伦/王智’],

[‘缝纫机乐队’,‘大鹏/乔杉/古力娜扎/李鸿其/韩童生’]],

columns=[‘电影名’,‘部分演员’])

print(df)

根据’/'拆分为列表

df[‘部分演员’] = df[‘部分演员’].str.split(“/”) # 转成列表

print(df)

df_new = df.explode(‘部分演员’)

print(df_new)

2.5 execl 数据透视表实现行转列

Excel 要实现行列转换,需要用到 Power Query,而Power Query 只有Excel 2016以上的版本才有!

第一步,【Ctrl A 全选数据】-【数据】-【从表格】,创建 Power Query,进入 Power Query界面。

第二步,添加辅助列。Excel 实现列转换,可以通过【添加辅助列】来实现该效果。而在 Power Query 有多种可以添加辅助列的方法。此处介绍两种方法法一,通过自定义列,添加辅助列法二,通过重复列,实现添加辅助列

第三步,进行透视列。【透视列】>【值列,自定义,选中需要透视的列】-【聚合值函数,选择不要聚合】-【确定】。

第四步,合并列。选中透视出来的列,右键,【合并列】-【自定义分隔符】-【确定】 。

最后,选中多余的列,删除!再进行【关闭并上载】。全部搞定!列转行后的数据

ps. execl实现的原文链接:https://zhuanlan.zhihu.com/p/315340716

2.6 Java 实现行转列

public class Row2Line {

public static void main(String[] args) throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {

//你提供的对象列表,需要转换的原数据

List StudentGrandList = getStudentGrandList();

//实现行转列的算法

List<List> convertedTable = convert(StudentGrandList);

//打印转换后的集合,查看结果

print(convertedTable);

//剩下的可以根据实际需求,将转换好的集合传给前端、或随意处理

}

private static List<List> convert(List StudentGrandList)

throws IntrospectionException, IllegalAccessException, InvocationTargetException {//取得StudentGrand的属性,当然你也可以用list = {“id”, “name”, …}

Field[] declaredFields = StudentGrand.class.getDeclaredFields();

List<List> convertedTable = new ArrayList<List>();

//多少个属性表示多少行,遍历行

for (Field field : declaredFields) {

field.setAccessible(true);

ArrayList rowLine = new ArrayList();

//list多少个StudentGrand实体类表示有多少列,遍历列

for (int i = 0, size = StudentGrandList.size(); i < size; i++) {

//每一行的第一列对应StudentGrand字段名

//所以新table的第一列要设置为字段名

if(i == 0){

rowLine.add(field.getName());

}

//新table从第二列开始,某一列的某个值对应旧table第一列的某个字段

else{

StudentGrand StudentGrand = StudentGrandList.get(i);

String val = (String) field.get(StudentGrand);//grand为int会报错

System.out.println(val);

rowLine.add(val);

}

}

convertedTable.add(rowLine);

}

return convertedTable;

}

//测试用数据,实际应该从数据库查询,传过来的

private static List getStudentGrandList () {

List list = new ArrayList();

list.add(new StudentGrand(“001”, “toni”, “语文”, “98”));

list.add(new StudentGrand(“001”, “toni”, “数学”, “98”));

list.add(new StudentGrand(“001”, “toni”, “外语”, “98”));

list.add(new StudentGrand(“001”, “toni”, “体育”, “98”));

list.add(new StudentGrand(“006”, “amy”, “语文”, “98”));

list.add(new StudentGrand(“006”, “amy”, “数学”, “98”));

list.add(new StudentGrand(“006”, “amy”, “外语”, “98”));

list.add(new StudentGrand(“006”, “amy”, “体育”, “98”));

list.add(new StudentGrand(“003”, “安东尼”, “语文”, “98”));

list.add(new StudentGrand(“003”, “安东尼”, “数学”, “98”));

list.add(new StudentGrand(“003”, “安东尼”, “外语”, “98”));

list.add(new StudentGrand(“003”, “安东尼”, “体育”, “98”));

return list;

}

//打印查看结果

private static void print(List<List> convertedTable) {

//String json = JSONArray.formObject(convertedTable).toString();

for (List list : convertedTable) {

for (String string : list) {

System.out.print(string+" ");

}

System.out.println();

}

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

片转存中…(img-R1PXjyas-1713218467403)]

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

img
  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值