MySQL中的经典面试题——行转列(列转行)

这篇具有很好参考价值的文章主要介绍了MySQL中的经典面试题——行转列(列转行)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1、简介:  

1. 行转列(Pivot):

2. 列转行(Unpivot):

2、行转列,列转行的思想

3、实现

3.1、实现行转列

3.2、总结(行转列)实现的两种方法  

3.3、实现(列转行) 

3.4、总结 (列转行)


1、简介:  

        在MySQL中,行转列(Pivot)和列转行(Unpivot)是用于改变数据表格布局的概念,行转列和列转行是在特定数据转换需求下使用的技术,可以帮助改变数据的呈现方式,以适应不同的分析和报告要求。具体的实现方法会因实际需求和查询的具体情况而有所不同。

1. 行转列(Pivot):

        行转列是指将原始数据表格中的行转换为列。这种操作常用于将某一列的值作为新的列名,并将对应的值填入相应的位置。例如,将某个学生在不同科目上的成绩从纵向布局转换为横向布局。

2. 列转行(Unpivot):

        列转行是指将原始数据表格中的列转换为行。这种操作常用于将多个列的值转换为一列,并将原来的列名作为新的列。例如,将不同科目的成绩从横向布局转换为纵向布局。

2、行转列,列转行的思想

        行转列:首先对于很分散的数据来说,我们的行要想把它转换为列,这就需要我们有一个和的思想,这在我们MySQL的学习过程中,聚合函数的分组聚合就尤为重要,所以在行转列的过程中,聚合函数,group by 分组列最为重要。也就可以通过使用聚合函数和条件语句(如`CASE WHEN`)来实现。具体实现方法因查询需求而异,一般使用`GROUP BY`进行分组和聚合。

        列转行:那么对于一个跟聚合的数据我们又如何把它拆散,拆散之后我们又该进行什么操作,这就要想到我们将打散了的数据聚合在一起,也就是使用到我们的UNION ALL,将多个查询的结果组合在一起,并在结果中添加一个代表原列名的新列。每个查询都需选择一个子集,代表一个原始列。

3、实现

3.1、实现行转列

/*-------------------------- MySQL中的行转列和列转行 ---------------------------------
-- MySQL中的行转列
-- 对于我们的stu_score这张表,我们的数据展示是以行为主,同一个人物的信息被拆分为多个行,行转列的思想就是想把多行转换为一行数据
  MySQL中的行转列和列转行
          张三          语文          78
          张三          数学          87
          张三          英语          65
          李四          语文          88
          李四          数学          90
          李四          英语          98
          王五          语文          73
          王五          数学          88
          王五          英语          90
其目的就是将我们的数据展示为:
          name      语文          数学           英语
          张三       78            87            65
          李四       88            90            98
          王五       73            88            90

  假想:伪列,上诉中的表每行都存在着我们的人物姓名,学科名称,即一课学科的信息,现在我们把所有的每一行都看作是包含语文、数学、英语的
          张三          语文          78          null (数学)           null (英语)
          张三          数学          87          null (语文)           null (英语)
          张三          英语          65
          李四          语文          88
          李四          数学          90
          李四          英语          98
          王五          语文          73
          王五          数学          88
          王五          英语          90
  行转列的解题步骤:
    1、确定分组列,转换列,数据列---确定数据中哪一个作为分组列(找同名字段),哪一个作为转换列,哪一个作为数据列
    2、生成伪列---声明伪列,即保证结构的完整性
    3、做分组查询---为第四步做铺垫,分组查询通常跟我们的聚合函数一起使用
    4、选择合适的聚合函数---使用聚合函数,把结构中的数据正确的计算出来

 */

1) 确定我们的分组列,扫视整张表,只有我们姓名没变,所以姓名作为我们的分组列,其次我们转换列,我们需要把对应的学科成绩转换成列,依次,成绩信息就作为我们的数据列

2)生成伪列

-- 生成伪列

select name,
       case subject when '语文' then score else null end as 'chinese',
       case subject when '数学' then score else null end as 'math',
       case subject when '英语' then score else null end as 'english'
from stu_score;

  结果:

mysql列转行,MySQL,mysql,数据库,sql

3)确定我们的分组列为name

4)因为我们的分组语句通常跟我们的聚合函数搭配使用

-- 通过聚合函数和分组语句:

select name,max(chinese) as '语文成绩',max(math) as '数学成绩',max(english) as '英语成绩'
from (select name,
       case subject when '语文' then score else null end as 'chinese',
       case subject when '数学' then score else null end as 'math',
       case subject when '英语' then score else null end as 'english'
from stu_score) temp
group by name;

结果:

 mysql列转行,MySQL,mysql,数据库,sql

3.2、总结(行转列)实现的两种方法  

两步法:
公式:
select 分组列,
      聚合函数(m1)as 列名1,
      聚合函数(m2)as 列名2,
      聚合函数(m3)as 列名3,
from (select *,
    case 转换列 when 转换列值1 then 数据列 else .... end as m1,    
    case 转换列 when 转换列值2 then 数据列 else .... end as m2,
    case 转换列 when 转换列值3 then 数据列 else .... end as m3
    from 表名)临时表名
group by 分组列;



一步法:
公式:
select 分组列,
    聚合函数(case 转换列 when 转换列值1 then 数据列 else .... end) as 列名1,    
    聚合函数(case 转换列 when 转换列值2 then 数据列 else .... end) as 列名2,
    聚合函数(case 转换列 when 转换列值3 then 数据列 else .... end) as 列名3
    ...
from 表名
group by 分组列;

3.3、实现(列转行) 

  创建数据表:

-- 将上面的行转列的查询结果存储为学生信息的表

create table stu_score_row_columns as (
    select name,
    max(case subject when '语文' then score else null end) as '语文',
    max(case subject when '数学' then score else null end) as '数学',
    max(case subject when '英语' then score else null end) as '英语'
from stu_score group by name
);
/*
数据展示:
    name 语文 数学 英语
    张三  78  87  65
    李四  88  90  98
    王五  73  88  90

列转行之后:思想:先转换我们第一行的数据,然后一层一层拼接使用union all来操作
    张三          语文          78
    张三          数学          87
    张三          英语          65
分析:
    1、表中的张三是通过表中的name所得到,语文作为我们的表头,可以通过'列名'获取,列所对应的值通过列名直接指定
 */

   结果:

mysql列转行,MySQL,mysql,数据库,sql

   实现列转行

 -- 先获取一行的数据,其中,subject列的值始终为字符串'语文',score列的值将与stu_score_row_columns表中的语文列的值相对应。

select name,'语文' as subject,语文 as 'score' from stu_score_row_columns
union all
select name,'数学' as subject,数学 as 'score' from stu_score_row_columns
union all
select name,'英语' as subject,英语 as 'score' from stu_score_row_columns
order by name;

  结果:

mysql列转行,MySQL,mysql,数据库,sql

3.4、总结 (列转行)

总结:实现列转行方法
解题步骤:
    1、确定转换列,非转换列
    2、生成新列
    3、使用union或union all来进行合并
    4、根据需要进行order by排序操作

公式:
select 非转换列,'转换列1' as 新转换列名,转换列1 as 新数据列名 from 表名
union all
select 非转换列,'转换列2' as 新转换列名,转换列2 as 新数据列名 from 表名
union all
select 非转换列,'转换列3' as 新转换列名,转换列3 as 新数据列名 from 表名  
order by ....;s

注意:

        新转换列名和新数据列名必须保持一致。

4、动手练习

行转列(Pivot)题目:
1.  给定一个订单表格,包含订单号(order_number)、产品名称(product_name)和销售数量(quantity)三个字段,将该表格行转列,以订单号作为列名,各产品名称对应的销售数量作为相应的值。

创建表,并插入数据:

 create table order_tab(
     order_number int comment '订单号',
     product_name varchar(40) comment '产品名称',
     quantity int comment '销售数量'
 ) COMMENT '订单表';

insert into order_tab(order_number, product_name, quantity) values (1,'球鞋',3),
                                                                   (1,'羽毛球',3),
                                                                   (3,'羽毛球',2),
                                                                   (2,'球鞋',6),
                                                                   (4,'矿泉水',3),
                                                                   (2,'苏打水',1),
                                                                   (2,'矿泉水',4);
-- 确定我们的行转列
select order_number '订单编号',
       sum(case when product_name = '球鞋' then quantity else 0 end) as '球鞋',
       sum(case when product_name = '羽毛球' then quantity else 0 end) as '羽毛球',
       sum(case when product_name = '矿泉水' then quantity else 0 end) as '矿泉水',
       sum(case when product_name = '苏打水' then quantity else 0 end) as '苏打水'
from order_tab group by order_number order by order_number;

  结果:

mysql列转行,MySQL,mysql,数据库,sql

列转行(Unpivot)题目:
1. 假设有一个销售数据表格,包含年份(year)、产品A的销售量(product_a_sales)和产品B的销售量(product_b_sales)两个字段,将该表格列转行,以年份为一列,并列出每个产品和对应的销售量。
2. 给定一个市场调查数据表格,包含城市名称(city_name)、产品A的需求量(product_a_demand)和产品B的需求量(product_b_demand)两个字段,将该表格列转行,以城市名称为一列,并列出每个产品和对应的需求量。

  解题2:

  数据准备:

-- 实现列转行(数据准备)
create table market_servey(
    city_name varchar(30) comment '城市名称',
    product_a_demand int comment '产品A的需求量',
    product_b_demand int comment '产品B的需求量'
);

insert into market_servey(city_name, product_a_demand, product_b_demand) values ('贵阳',20,30),
                                                                                ('毕节',30,10),
                                                                                ('遵义',15,50),
                                                                                ('铜仁',60,10),
                                                                                ('黔东南',10,16);

 mysql列转行,MySQL,mysql,数据库,sql

  代码:

-- 实现列转行(列转行使用到union all)

select city_name,'product_a_demand' as '产品名称',product_a_demand as '产品数量' from market_servey
union all
select city_name,'product_b_demand' as '产品名称',product_b_demand as '产品数量' from market_servey
order by city_name;

  结果:

mysql列转行,MySQL,mysql,数据库,sql文章来源地址https://www.toymoban.com/news/detail-769760.html

到了这里,关于MySQL中的经典面试题——行转列(列转行)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SQL行转列、列转行(SQL Server版)

    在SQL Server中使用SQL实现行转列、列转行,可以使用多种方法,在SQL 2005以前可以使用case when then...语句,但这种方法的问题在于列举的列名要写死,如果列名很多,case when 语句会很长,并不优雅。所以需要SQL Server提供新的语句能够实现。在2005版本就推出了pivot/unpivot,

    2024年02月08日
    浏览(58)
  • Mysql行转列函数

    group_concat() 例: select oid from Test;  select group_concat( oid ) from Test;

    2024年02月14日
    浏览(40)
  • mysql 行转列

    以下是其中比较常见的几种方法: 使用GROUP_CONCAT函数 可以使用GROUP_CONCAT函数将多行数据合并为一行,并以逗号或其他分隔符进行分隔。通过SELECT语句和GROUP BY子句,可以将数据行转换为列。具体语法如下: 其中,id表示非透视列,status表示需要转换为列的字段,value表示需要

    2024年02月16日
    浏览(52)
  • oracle 行转列和列转行的几种方式

    1、准备数据:REST表 2、查询数据  3、行转列 方式1:使用 case when  then方式 case 条件 when 值1 then 返回值1 when 值2 then 返回值2 .......... else 默认值 end case when 另一种方式:         case when 条件 = 值1 then 返回值1          case when 条件 = 值1 then 返回值1          else

    2024年02月05日
    浏览(48)
  • Oracle行转列(pivot)和Oracle列转行(unpivot)

            行变列,列变行在 生成报表 的时候经常遇到,行变列叫做\\\"Pivot”, 反之叫做\\\"Unpivot”。 在Oracle11g之前,一般都是通过case来实现,但是Oracle11g及其以后直接支持PIVOT和UNPIVOT的操作。         语法:          for 可以看成循环,for前是行转列后显示的值( 这里必须

    2023年04月15日
    浏览(39)
  • 5分钟搞懂MySQL - 行转列

    小伙伴想精准查找自己想看的MySQL文章?喏 → MySQL专栏目录 | 点击这里   MySQL 行转列 ,对经常处理数据的同学们来说,一定是不陌生的,甚至是印象深刻,因为它大概率困扰过你,让你为之一愣~ 但当你看到本文后,这个问题就不在是问题,及时收藏,以后谁再问你这个问

    2023年04月08日
    浏览(58)
  • Mysql 行转列,把逗号分隔的字段拆分成多行

    源数据 变更后的数据 第一种 先执行下面的SQL,看不看能不能执行,如果有结果,代表数据库版本是可以的,可以看下面和自己表关联的SQL,如果不行用第二种。 示例SQL 和业务结合在一起使用 其核心在于 mysql.help_topic ,但是版本太低的数据库版本不支持,如果不支持,可以

    2024年02月02日
    浏览(42)
  • Mysql一维表转二维表,动态的行转列

    背景 想利用Grafana做数据展示,将一维的长表优化成二维数据表格展示。 将一维表转换为二维表,也就是将行转换为列,可以使用MySQL的PIVOT语句来完成。 PIVOT是一种在关系型数据库中将行转换为列的技术。在MySQL中,可以使用PIVOT语句将普通的查询结果转换为一个带有动态列

    2024年02月15日
    浏览(42)
  • mysql~GROUP_CONCAT实现关系表的行转列

    GROUP_CONCAT 是 MySQL 中用于将查询结果集中的多行数据合并为单个字符串的聚合函数。它将每行数据的指定字段值连接起来,并以指定的分隔符分隔,最终返回一个包含所有值的字符串。 以下是 GROUP_CONCAT 函数的一般语法: column_name:要连接的字段名。 SEPARATOR:可选参数,用于

    2024年04月12日
    浏览(36)
  • greenplum行转列

    项目中需要将150w的数据转为1500列的大宽表数据。 最开始尝试了网上提供的两种方法: 实际业务中10行*1500列数据查询并插入需要25秒左右(测试服务器性能比较差) case when的问题是每个case when的语句都会把分组后的数据判断一下,时间复杂度为O²(O为行转列后的列数),非

    2024年02月03日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包