MySQL讲义第 33 讲——select 查询之静态交叉表查询

文章目录

  • MySQL讲义第 33 讲——select 查询之静态交叉表查询
    • 一、数据准备
    • 二、交叉表的形式
    • 三、静态交叉表的实现
      • 1、根据 user、goods 和 orders 三张表查询每个用户每种类别的商品的消费金额

交叉表查询是将来源于某个表中的字段进行分组,一组列在交叉表左侧,一组列在交叉表上部,并在交叉表行与列交叉处显示表中某个字段的各种计算值。交叉表分为静态交叉表和动态交叉表,其中静态交叉表中的列是固定的,而动态交叉表中的列需要动态生成。

使用交叉表查询来计算和重构数据,可以简化数据分析。交叉表查询计算数据的总和,平均值,计数及其他类型的统计,并将它们分组,一组列在数据表左侧作为交叉表的行字段,另一组列在数据表的顶端作为交叉表的列字段。

一、数据准备

有下面三张表,表结构和数据如下:

mysql> select * from users;
+---------+-----------+-------------+-----------+
| user_id | user_name | phone       | addr      |
+---------+-----------+-------------+-----------+
| 2020101 | 张华      | 15937310588 | Xinxiang  |
| 2020102 | 张毅德    | 13783730566 | Xinxiang  |
| 2020103 | 刘选德    | 13602313277 | Beijing   |
| 2020104 | 赵紫龙    | 13703713731 | Zhengzhou |
| 2020105 | 关云常    | 13637312446 | Xinxiang  |
| 2020106 | 刘蓓      | 15037130526 | Zhengzhou |
| 2020107 | 刘晓璐    | 18237150566 | Zhengzhou |
+---------+-----------+-------------+-----------+
7 rows in set (0.00 sec)mysql> select * from goods;
+----------+------------+---------+------------+
| goods_id | goods_name | price   | categories |
+----------+------------+---------+------------+
|     1101 | 帽子       |   58.00 | 服装       |
|     1102 | 裤子       |  150.00 | 服装       |
|     1103 | 运动鞋     |  580.00 | 服装       |
|     1104 | 西服       | 1508.00 | 服装       |
|     2201 | 香蕉       |    2.58 | 水果       |
|     2202 | 苹果       |    4.98 | 水果       |
|     2203 | 葡萄       |    6.88 | 水果       |
|     3301 | 笔记本     |   25.00 | 文具       |
|     3302 | 钢笔       |   25.80 | 文具       |
+----------+------------+---------+------------+
9 rows in set (0.00 sec)mysql> select * from orders;
+----------+---------+----------+----------+---------------------+
| order_id | user_id | goods_id | quantity | order_date          |
+----------+---------+----------+----------+---------------------+
|        1 | 2020101 |     1101 |     1.00 | 2020-10-22 09:05:21 |
|        2 | 2020101 |     1102 |     1.00 | 2020-10-20 00:00:00 |
|        3 | 2020101 |     2201 |     2.50 | 2020-10-21 00:00:00 |
|        4 | 2020101 |     2202 |     4.50 | 2020-10-21 00:00:00 |
|        5 | 2020101 |     2203 |     2.50 | 2020-10-20 00:00:00 |
|        6 | 2020101 |     3301 |     2.00 | 2020-10-20 00:00:00 |
|        7 | 2020102 |     2201 |     3.50 | 2020-10-22 00:00:00 |
|        8 | 2020102 |     2202 |     2.00 | 2020-10-22 00:00:00 |
|        9 | 2020103 |     2202 |     2.00 | 2020-10-19 00:00:00 |
|       10 | 2020103 |     2203 |     1.20 | 2020-10-19 00:00:00 |
|       11 | 2020103 |     3302 |     1.00 | 2020-10-20 00:00:00 |
|       12 | 2020103 |     1101 |     1.00 | 2020-10-19 00:00:00 |
|       13 | 2020103 |     1102 |     1.00 | 2020-10-20 00:00:00 |
|       14 | 2020104 |     1102 |     1.00 | 2020-10-20 00:00:00 |
|       15 | 2020104 |     2201 |     1.80 | 2020-10-19 00:00:00 |
|       16 | 2020104 |     2202 |     3.20 | 2020-10-19 00:00:00 |
|       17 | 2020104 |     3302 |     1.00 | 2020-10-20 00:00:00 |
|       18 | 2020105 |     1103 |     1.00 | 2020-10-21 00:00:00 |
|       19 | 2020105 |     1104 |     1.00 | 2020-10-21 00:00:00 |
|       20 | 2020105 |     2201 |     1.80 | 2020-10-22 00:00:00 |
|       21 | 2020105 |     2202 |     3.20 | 2020-10-22 00:00:00 |
|       22 | 2020105 |     2203 |     2.00 | 2020-10-21 00:00:00 |
|       23 | 2020105 |     3302 |     1.00 | 2020-10-21 00:00:00 |
|       24 | 2020106 |     1102 |     1.00 | 2020-10-22 00:00:00 |
|       25 | 2020106 |     1103 |     1.00 | 2020-10-22 00:00:00 |
|       26 | 2020106 |     1104 |     1.00 | 2020-10-22 00:00:00 |
|       27 | 2020106 |     2201 |     2.00 | 2020-10-21 00:00:00 |
|       28 | 2020106 |     2202 |     3.50 | 2020-10-21 00:00:00 |
|       29 | 2020106 |     2203 |     5.50 | 2020-10-21 00:00:00 |
+----------+---------+----------+----------+---------------------+
29 rows in set (0.00 sec)

二、交叉表的形式

交叉表又称为行列转换,就是把下面的表1 转换为表2(交叉表)。

select stu_name,c_name,score
from stu s,course c,score sc where s.stu_id=sc.stu_id and c.c_id=sc.c_id;
--################################  表1  #############################################
+-----------+-----------------------+-------+
| stu_name  | c_name                | score |
+-----------+-----------------------+-------+
| 王占峰    | 管理学原理            |    88 |
| 王占峰    | 政治经济学            |    75 |
| 王占峰    | 数据库系统原理        |    89 |
| 王占峰    | 企业管理概论          |    95 |
| 刘国强    | 管理学原理            |    65 |
| 刘国强    | 政治经济学            |    79 |
| 刘国强    | 数据库系统原理        |    72 |
| 刘国强    | 企业管理概论          |    91 |
| 王艳艳    | 管理学原理            |    84 |
| 王艳艳    | 政治经济学            |    76 |
| 王艳艳    | 数据库系统原理        |    68 |
| 王艳艳    | 企业管理概论          |    92 |
| 赵牡丹    | 管理学原理            |    64 |
| 赵牡丹    | 政治经济学            |    75 |
| 赵牡丹    | 数据库系统原理        |    81 |
| 赵牡丹    | 企业管理概论          |    90 |
+-----------+----------------------+-------+
--################################  表2  #############################################
+-----------+--------------+---------------+-------------------+------------------+--------+
| stu_name  | 管理学原理    | 政治经济学    | 数据库系统原理      | 企业管理概论      | 总分   |
+-----------+---------------+---------------+------------------+------------------+--------+
| 刘国强    |            65 |            79 |                72 |               91 |    307 |
| 王占峰    |            88 |            75 |                89 |               95 |    347 |
| 王艳艳    |            84 |            76 |                68 |               92 |    320 |
| 赵牡丹    |            64 |            75 |                81 |               90 |    310 |
+-----------+---------------+---------------+-----------------------+--------------+--------+

三、静态交叉表的实现

生成交叉表的基本方法为:
(1)按照交叉表的行字段进行分组(比如上例中的 stu_name)。
(2)对要转换为列的行字段(比如上例中的 c_name)进行统计,在统计函数中使用 IF 函数对数据进行筛选,生成列字段。

例如:

1、根据 user、goods 和 orders 三张表查询每个用户每种类别的商品的消费金额

第一步:根据 u.user_name 和 categories 两个字段分组,统计消费金额

mysql> SELECT-> u.user_name as 用户姓名,-> categories as 消费类别,-> sum(o.quantity * g.price) as 总金额-> FROM-> users u JOIN orders o ON u.user_id = o.user_id -> JOIN goods g ON o.goods_id = g.goods_id-> GROUP BY u.user_name,categories;
+--------------+--------------+-----------+
| 用户姓名     | 消费类别     | 总金额    |
+--------------+--------------+-----------+
| 关云常       | 文具         |   25.8000 |
| 关云常       | 服装         | 2088.0000 |
| 关云常       | 水果         |   34.3400 |
| 刘蓓         | 服装         | 2238.0000 |
| 刘蓓         | 水果         |   60.4300 |
| 刘选德       | 文具         |   25.8000 |
| 刘选德       | 服装         |  208.0000 |
| 刘选德       | 水果         |   18.2160 |
| 张华         | 文具         |   50.0000 |
| 张华         | 服装         |  208.0000 |
| 张华         | 水果         |   46.0600 |
| 张毅德       | 水果         |   18.9900 |
| 赵紫龙       | 文具         |   25.8000 |
| 赵紫龙       | 服装         |  150.0000 |
| 赵紫龙       | 水果         |   20.5800 |
+--------------+--------------+-----------+
15 rows in set (0.00 sec)

第二步:对消费类别字段分别按文具、服装、水果为条件进行筛选,然后转换为列,代码如下:

mysql> SELECT-> u.user_name as 用户,-> sum(if(categories = '服装',o.quantity * g.price,0)) as 服装,-> sum(if(categories = '文具',o.quantity * g.price,0)) as 文具,-> sum(if(categories = '水果',o.quantity * g.price,0)) as 水果,-> sum(o.quantity * g.price) as 总金额-> FROM-> users u JOIN orders o ON u.user_id = o.user_id -> JOIN goods g ON o.goods_id = g.goods_id-> GROUP BY u.user_name;
+-----------+-----------+---------+---------+-----------+
| 用户      | 服装      | 文具    | 水果    | 总金额    |
+-----------+-----------+---------+---------+-----------+
| 关云常    | 2088.0000 | 25.8000 | 34.3400 | 2148.1400 |
| 刘蓓      | 2238.0000 |  0.0000 | 60.4300 | 2298.4300 |
| 刘选德    |  208.0000 | 25.8000 | 18.2160 |  252.0160 |
| 张华      |  208.0000 | 50.0000 | 46.0600 |  304.0600 |
| 张毅德    |    0.0000 |  0.0000 | 18.9900 |   18.9900 |
| 赵紫龙    |  150.0000 | 25.8000 | 20.5800 |  196.3800 |
+-----------+-----------+---------+---------+-----------+
6 rows in set (0.00 sec)

第三步:添加总计行

mysql> SELECT-> IFNULL(u.user_name,'总计') as 用户,-> sum(if(categories = '服装',o.quantity * g.price,0)) as 服装,-> sum(if(categories = '文具',o.quantity * g.price,0)) as 文具,-> sum(if(categories = '水果',o.quantity * g.price,0)) as 水果,-> sum(o.quantity * g.price) as 总金额-> FROM-> users u JOIN orders o ON u.user_id = o.user_id -> JOIN goods g ON o.goods_id = g.goods_id-> GROUP BY u.user_name-> WITH rollup;
+-----------+-----------+----------+----------+-----------+
| 用户      | 服装      | 文具     | 水果     | 总金额    |
+-----------+-----------+----------+----------+-----------+
| 关云常    | 2088.0000 |  25.8000 |  34.3400 | 2148.1400 |
| 刘蓓      | 2238.0000 |   0.0000 |  60.4300 | 2298.4300 |
| 刘选德    |  208.0000 |  25.8000 |  18.2160 |  252.0160 |
| 张华      |  208.0000 |  50.0000 |  46.0600 |  304.0600 |
| 张毅德    |    0.0000 |   0.0000 |  18.9900 |   18.9900 |
| 赵紫龙    |  150.0000 |  25.8000 |  20.5800 |  196.3800 |
| 总计      | 4892.0000 | 127.4000 | 198.6160 | 5218.0160 |
+-----------+-----------+----------+----------+-----------+
7 rows in set (0.00 sec)
--说明:使用 IFNULL 函数把最后一行第一列的 NULL 替换成 '总计'。

MySQL讲义第 33 讲——select 查询之静态交叉表查询相关推荐

  1. MySQL讲义第 39 讲——select 查询之函数(2):日期时间型函数

    MySQL讲义第39讲--select 查询之函数(2):日期时间型函数 文章目录 MySQL讲义第39讲--select 查询之函数(2):日期时间型函数 一.数据准备 二.MySQL 日期时间型函 ...

  2. MySQL讲义第 41 讲——select 查询之函数(4):流程控制函数

    MySQL讲义第41讲--select 查询之函数(4):流程控制函数 文章目录 MySQL讲义第41讲--select 查询之函数(4):流程控制函数 一.数据准备 二.MySQL 流程控制函数介绍 ...

  3. MySQL讲义第 40 讲——select 查询之函数(3):数学函数

    MySQL讲义第40讲--select 查询之函数(3):数学函数 文章目录 MySQL讲义第40讲--select 查询之函数(3):数学函数 一.数据准备 二.MySQL 数学函数介绍 1.ABS ...

  4. MySQL讲义第 35 讲——select 查询之正则表达式

    MySQL讲义第 35 讲--select 查询之正则表达式 文章目录 MySQL讲义第 35 讲--select 查询之正则表达式 一.正则表达式匹配规则 二.数据准备 三.查询包含某些字符的字段信 ...

  5. MySQL讲义第27讲——select 查询之自连接查询

    MySQL讲义第27讲--select 查询之自连接查询 文章目录 MySQL讲义第27讲--select 查询之自连接查询 一.数据准备 二.对自连接的理解 三.把以上的查询用自连接表示 顾名思义, ...

  6. MySQL讲义第 32 讲——select 查询之 select 语句的执行顺序

    MySQL讲义第 32 讲--select 查询之 select 语句的执行顺序 文章目录 MySQL讲义第 32 讲--select 查询之 select 语句的执行顺序 一.SELECT 语句的语 ...

  7. MySQL讲义第 30 讲——select 查询之子查询

    MySQL讲义第 30 讲--select 查询之子查询 文章目录 MySQL讲义第 30 讲--select 查询之子查询 一.标量子查询 1.查询高于所有员工平均工资的员工信息 2.查询工资比王涛 ...

  8. MySQL讲义第 36 讲——select 查询之 INTO OUTFILE参数

    MySQL讲义第 36 讲--select 查询之 INTO OUTFILE参数 文章目录 MySQL讲义第 36 讲--select 查询之 INTO OUTFILE参数 一.SELECT ... ...

  9. 数据库系统原理与应用教程(052)—— MySQL 的数据完整性(十四):交叉表查询(行列转换)

    数据库系统原理与应用教程(052)-- MySQL 的数据完整性(十四):交叉表查询(行列转换) 目录 数据库系统原理与应用教程(052)-- MySQL 的数据完整性(十四):交叉表查询(行列转换) ...

最新文章

  1. Struts2学习入门
  2. 写了 30 万行基础设施代码后,我们得出 5 个有用的经验
  3. 刚学GDI+和.Net WinForm控件开发时做的Training Project
  4. POJ 3259 SPFA
  5. php myadmin怎么用,关于apachemysqlphpmyadmin的安装与配置
  6. 算法——常用的数据结构/模板/基础知识
  7. requirejs页面刷新失效js报错问题解决方案
  8. 下载地址jquery upload file demo (C#)
  9. 基于Wiremock创建Mock Service平台
  10. 纯html 404页面,一款纯css3实现的漂亮的404页面_html/css_WEB-ITnose
  11. CSDN-markdown编辑器语法——背景色
  12. java代理模式租房案例
  13. 另类网站版式设计欣赏
  14. 小刘同学的第五十五篇博文
  15. missing separator 解决方法
  16. 如何使用Loadrunner12在win10系统 最新版本谷歌浏览器录制脚本
  17. 初步了解3dmax建模方式和多边形建模
  18. 2013上半年,Google Chrome正式版最新版本,又增加什么小功能!
  19. iOS 10.2 越狱更新到yalu102 beta7,很稳定,很多注意事项及修复ssh和scp连接教程
  20. 中国风味苹果酒市场现状研究分析与发展前景预测报告(2022)

热门文章

  1. 垂直行业(新站)SEO流量快速起飞的核心思路
  2. Mac软件卸载后图标任然残留的删除方法
  3. 基于mysql8实现数据库安全审计、容灾备份、数据恢复实验
  4. 404页面换成公益宝贝回家页面
  5. 洛谷 P4471 [BJWC2018]词韵 (字典树)
  6. 毕业设计 stm32智能路灯智能灯控系统 - LoRa远程通信 单片机
  7. 《大数据集成(1)》一导读
  8. 1号店关于秒杀架构的设计
  9. 计算机xp bios密码设置方法,电脑开机密码怎么设置_教您各系统设置方法
  10. 计算机桌面图案在哪里更改,桌面图标更改方法