我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Oracle中如何实现数据透视表

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Oracle中如何实现数据透视表

这篇文章主要介绍Oracle中如何实现数据透视表,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

使用 CASE 表达式实现数据透视表

数据透视表的本质就是按照行和列的不同组合进行数据分组,然后对结果进行汇总;因此,它和数据库中的分组(GROUP BY)和聚合函数(COUNT、SUM、AVG 等)的功能非常类似。

我们首先使用以下 GROUP BY 子句对销售数据进行分类汇总:

select coalesce(product, '【全部产品】') "产品",    coalesce(channel, '【所有渠道】') "渠道",    coalesce(to_char(saledate, 'YYYYMM'), '【所有月份】') "月份",    sum(amount) "销量"from sales_datagroup by rollup (product,channel,to_char(saledate, 'YYYYMM'));

以上语句按照产品、渠道以及月份进行汇总;rollup 选项用于生成不同层次的小计、合计以及总计;coalesce 函数用于将汇总行中的 NULL 值显示为相应的信息。查询返回的结果如下:

产品      |渠道      |月份       |销量    |
---------|---------|-----------|-------|
桔子      |京东      |201901    |  41289|
桔子      |京东      |201902    |  43913|
桔子      |京东      |201903    |  49803|
桔子      |京东      |201904    |  49256|
桔子      |京东      |201905    |  64889|
桔子      |京东      |201906    |  62649|
桔子      |京东      |【所有月份】| 311799|
桔子      |店面      |201901    |  41306|
桔子      |店面      |201902    |  37906|
桔子      |店面      |201903    |  48866|
桔子      |店面      |201904    |  48673|
桔子      |店面      |201905    |  58998|
桔子      |店面      |201906    |  58931|
桔子      |店面      |【所有月份】| 294680|
桔子      |淘宝      |201901    |  43488|
桔子      |淘宝      |201902    |  37598|
桔子      |淘宝      |201903    |  48621|
桔子      |淘宝      |201904    |  49919|
桔子      |淘宝      |201905    |  58530|
桔子      |淘宝      |201906    |  64626|
桔子      |淘宝      |【所有月份】| 302782|
桔子      |【所有渠道】|【所有月份】| 909261|
...
香蕉      |【所有渠道】|【所有月份】| 925369|
【全部产品】|【所有渠道】|【所有月份】|2771682|

实际上,我们已经得到了数据透视表的汇总结果,只不过需要将数据按照不同月份显示为不同的列;也就是需要将行转换为列,这个功能可以使用 CASE 表达式实现:

select coalesce(product, '【全部产品】') "产品", coalesce(channel, '【所有渠道】') "渠道",     sum(case to_char(saledate, 'YYYYMM') when '201901' then amount else 0 end) "一月",    sum(case to_char(saledate, 'YYYYMM') when '201902' then amount else 0 end) "二月",    sum(case to_char(saledate, 'YYYYMM') when '201903' then amount else 0 end) "三月",    sum(case to_char(saledate, 'YYYYMM') when '201904' then amount else 0 end) "四月",    sum(case to_char(saledate, 'YYYYMM') when '201905' then amount else 0 end) "五月",    sum(case to_char(saledate, 'YYYYMM') when '201906' then amount else 0 end) "六月",    sum(amount) "总计"from sales_datagroup by rollup (product, channel);

第一个 SUM 函数中的 CASE 表达式只汇总 201901 月份的销量,其他月份销量设置为 0;后面的 SUM 函数依次类推,得到了每个月的销量汇总和所有月份的总计。

产品       |渠道       |一月  |二月   |三月   |四月   |五月  |六月   |总计   |
----------|----------|------|------|------|------|------|------|-------|
桔子       |京东      | 41289| 43913| 49803| 49256| 64889| 62649| 311799|
桔子       |店面      | 41306| 37906| 48866| 48673| 58998| 58931| 294680|
桔子       |淘宝      | 43488| 37598| 48621| 49919| 58530| 64626| 302782|
桔子       |【所有渠道】|126083|119417|147290|147848|182417|186206| 909261|
苹果       |京东      | 38269| 40593| 56552| 56662| 64493| 62045| 318614|
苹果       |店面      | 43845| 40539| 44909| 55646| 56771| 64933| 306643|
苹果       |淘宝      | 42969| 43289| 48769| 58052| 58872| 59844| 311795|
苹果       |【所有渠道】|125083|124421|150230|170360|180136|186822| 937052|
香蕉       |京东      | 36879| 36981| 51748| 54801| 64936| 60688| 306033|
香蕉       |店面      | 41210| 39420| 50884| 52085| 60249| 67597| 311445|
香蕉       |淘宝      | 42468| 41955| 52780| 54971| 56504| 59213| 307891|
香蕉       |【所有渠道】|120557|118356|155412|161857|181689|187498| 925369|
【全部产品】|【所有渠道】|371723|362194|452932|480065|544242|560526|2771682|

Oracle 中的 decode 函数也可以实现类似 CASE 表达式的功能。

以上实现数据透视表的方法存在一定的局限性,假如还有 7 月份到 12 月份的销量需要统计,我们就需要修改查询语句增加这部分的处理。因此,Oracle 11g 引入了一个新的子句来实现自动的行转列:PIVOT。

使用 PIVOT 子句实现数据透视表

Oracle 中的 PIVOT 子句用于将行转换为列,基本语法如下:

SELECT col1, col2, ...FROM tblPIVOT ( pivot_clause, pivot_for_clause, pivot_in_clause);

PIVOT 子句包含 3 个部分:

  • pivot_clause,定义需要汇总的数据,也就是聚合函数。例如使用 SUM(amount) 汇总销量;

  • pivot_for_clause,指定需要从行转换成列的字段。例如使用 for saledate 将每个月的数据显示为一列;

  • pivot_in_clause,指定将 pivot_for_clause 字段中的哪些数据值转换为列。例如 in (‘201901', ‘201902') 表示只将 201901 和 201902 两个月份的数据转换为列。

对于上文中的示例,我们可以使用以下 PIVOT 子句:

with d(saledate, product, channel, amount) as ( select to_char(saledate, 'YYYYMM'),     product,     channel,     amount from sales_data)select *from dpivot ( sum(amount) for saledate in ('201901', '201902', '201903', '201904', '201905', '201906'))order by product, channel;

其中,PIVOT 子句按照月份对销量进行汇总并且将月份转换为列显示,返回的结果如下:

PRODUCT  |CHANNEL |'201901'|'201902'|'201903'|'201904'|'201905'|'201906'|
---------|--------|--------|--------|--------|--------|--------|--------|
桔子     |京东     |   41289|   43913|   49803|   49256|   64889|   62649|
桔子     |店面     |   41306|   37906|   48866|   48673|   58998|   58931|
桔子     |淘宝     |   43488|   37598|   48621|   49919|   58530|   64626|
苹果     |京东     |   38269|   40593|   56552|   56662|   64493|   62045|
苹果     |店面     |   43845|   40539|   44909|   55646|   56771|   64933|
苹果     |淘宝     |   42969|   43289|   48769|   58052|   58872|   59844|
香蕉     |京东     |   36879|   36981|   51748|   54801|   64936|   60688|
香蕉     |店面     |   41210|   39420|   50884|   52085|   60249|   67597|
香蕉     |淘宝     |   42468|   41955|   52780|   54971|   56504|   59213|

接下来我们需要增加一个总计行和总计列,为此可以先将 sales_data 数据进行分组统计然后再使用 PIVOT 子句进行转换:

with d(saledate, product, channel, amount) as ( select to_char(saledate, 'YYYYMM'),     product,     channel,     sum(amount) from sales_data group by rollup (to_char(saledate, 'YYYYMM'), product, channel)), pt as ( select * from d pivot (  sum(amount)  for saledate  in ('201901' s01, '201902' s02, '201903' s03, '201904' s04, '201905' s05, '201906' s06) ))select coalesce(product, '【全部产品】') "产品",    coalesce(channel, '【所有渠道】') "渠道",    s01 "一月", s02 "二月", s03 "三月", s04 "四月", s05 "五月", s06 "六月",    s01+s02+s03+s04+s05+s06 "总计"from ptorder by product, channel;

我们在 PIVOT 子句返回的结果之上增加了一个 SELECT 查询,并且修改了返回字段的名称,让结果更加接近 EXCEL 数据透视表:

产品       |渠道       |一月  |二月   |三月   |四月   |五月  |六月   |总计   |
----------|----------|------|------|------|------|------|------|-------|
桔子       |京东      | 41289| 43913| 49803| 49256| 64889| 62649| 311799|
桔子       |店面      | 41306| 37906| 48866| 48673| 58998| 58931| 294680|
桔子       |淘宝      | 43488| 37598| 48621| 49919| 58530| 64626| 302782|
桔子       |【所有渠道】|126083|119417|147290|147848|182417|186206| 909261|
苹果       |京东      | 38269| 40593| 56552| 56662| 64493| 62045| 318614|
苹果       |店面      | 43845| 40539| 44909| 55646| 56771| 64933| 306643|
苹果       |淘宝      | 42969| 43289| 48769| 58052| 58872| 59844| 311795|
苹果       |【所有渠道】|125083|124421|150230|170360|180136|186822| 937052|
香蕉       |京东      | 36879| 36981| 51748| 54801| 64936| 60688| 306033|
香蕉       |店面      | 41210| 39420| 50884| 52085| 60249| 67597| 311445|
香蕉       |淘宝      | 42468| 41955| 52780| 54971| 56504| 59213| 307891|
香蕉       |【所有渠道】|120557|118356|155412|161857|181689|187498| 925369|
【全部产品】|【所有渠道】|371723|362194|452932|480065|544242|560526|2771682|

PIVOT 子句也可以一次执行多个聚合操作,或者按照多个字段进行分组。例如:

with d(saledate, product, channel, amount) as ( select to_char(saledate, 'YYYYMM'), product, channel, amount from sales_data where to_char(saledate, 'YYYYMM') in ('201901', '201902', '201903'))select *from dpivot ( sum(amount) for (channel, saledate) in (('淘宝','201901'), ('店面','201901'), ('京东','201901'),   ('淘宝','201902'), ('店面','201902'), ('京东','201902'),   ('淘宝','201903'), ('店面','201903'), ('京东','201903')));PRODUCT|'淘宝'_'201901'|'店面'_'201901'|'京东'_'201901'|'淘宝'_'201902'|'店面'_'201902'|'京东'_'201902'|'淘宝'_'201903'|'店面'_'201903'|'京东'_'201903'|-------|--------------|--------------|--------------|--------------|--------------|--------------|--------------|--------------|--------------|香蕉  |     42468|     41210|     36879|     41955|     39420|     36981|     52780|     50884|     51748|桔子  |     43488|     41306|     41289|     37598|     37906|     43913|     48621|     48866|     49803|苹果  |     42969|     43845|     38269|     43289|     40539|     40593|     48769|     44909|     56552|

以上查询返回了按照渠道和月份分组的汇总结果,并且将它们转换为列进行显示。

与 PIVOT 相反的操作是 UNPIVOT,它可以将列转换为行。我们通过以下示例将行专列之后的数据再转换回来:

with d(saledate, product, channel, amount) as ( select to_char(saledate, 'YYYYMM'),     product,     channel,     amount from sales_data),pt as ( select * from d pivot (  sum(amount)  for saledate  in ('201901' "201901", '201902' "201902", '201903' "201903", '201904' "201904", '201905' "201905", '201906' "201906") ))select * from ptunpivot ( amount for saledate IN ("201901", "201902", "201903", "201904", "201905", "201906"));

其中,unpivot 子句也有三个选项,将每个月份代表的列转换为 saledate 字段中的行,并且将对应的数据转换为 amount 字段中的行。以上查询返回的结果如下:

PRODUCT |CHANNEL |SALEDATE|AMOUNT|
--------|--------|--------|------|
桔子     |京东     |201901  | 41289|
桔子     |京东     |201902  | 43913|
桔子     |京东     |201903  | 49803|
桔子     |京东     |201904  | 49256|
桔子     |京东     |201905  | 64889|
桔子     |京东     |201906  | 62649|
香蕉     |店面     |201901  | 41210|
香蕉     |店面     |201902  | 39420|
香蕉     |店面     |201903  | 50884|
香蕉     |店面     |201904  | 52085|
香蕉     |店面     |201905  | 60249|
香蕉     |店面     |201906  | 67597|
...

如果想要解锁更多的 PIVOT 和 UNPIVOT 的使用姿势,可以参考官方文档中的定义和示例。

使用 MODEL 子句实现数据透视表

除了 PIVOT 子句之外,Oracle 还提供一个更加强大的功能:MODEL 子句。简单来说,MODEL 子句可以实现 EXCEL 等电子表格中基于位置和符号的单元格引用以及复杂的公式计算。

完整的 MODEL 子句比较复杂,我们直接看一个示例:

with d(saledate, product, channel, amount) as ( select to_char(saledate, 'YYYYMM'), product, channel, sum(amount) from sales_data group by rollup (to_char(saledate, 'YYYYMM'), product, channel))select coalesce(product, '【全部产品】') "产品",    coalesce(channel, '【所有渠道】') "渠道",    s201901 "一月", s201902 "二月", s201903 "三月", s201904 "四月", s201905 "五月", s201906 "六月",    stotal "总计"from dmodel  return updated rows partition by (product, channel) dimension by (saledate) measures (amount, 0 s201901, 0 s201902, 0 s201903, 0 s201904, 0 s201905, 0 s201906, 0 stotal) unique dimension rules upsert all (s201901[0] = amount['201901'],  s201902[0] = amount['201902'],  s201903[0] = amount['201903'],  s201904[0] = amount['201904'],  s201905[0] = amount['201905'],  s201906[0] = amount['201906'],  stotal[0] = sum(amount)[saledate between '201901' and '201906'])order by product, channel;

首先,通过 with 子句获得基本数据。然后使用 model 子句实现行专列;return updated rows 表示只返回计算模型更新和插入的数据,partition by 用于定义分区(产品和渠道),每个分区独立计算;dimension by 指定度量的维度(月份);measures 定义度量,amount 来自源表,0 s201901 表示创建一个度量 s201901 并初始化为 0;unique dimension 表示 partition by 加 dimension by 字段可以唯一确定模型中的每个单元格;rules 用于定义给每个度量赋值的表达式,upsert all 表示更新已有的单元格,如果不存在则创建单元格;s201901[0] 是通过位置对单元格的引用(维度为 1),amount[‘201901'] 表示月份 201901 对应的 amount 字段值,stotal[0] 是所有月份的总和。

以上语句返回的结果如下:

产品       |渠道       |一月  |二月   |三月   |四月   |五月  |六月   |总计   |
----------|----------|------|------|------|------|------|------|-------|
桔子       |京东      | 41289| 43913| 49803| 49256| 64889| 62649| 311799|
桔子       |店面      | 41306| 37906| 48866| 48673| 58998| 58931| 294680|
桔子       |淘宝      | 43488| 37598| 48621| 49919| 58530| 64626| 302782|
桔子       |【所有渠道】|126083|119417|147290|147848|182417|186206| 909261|
苹果       |京东      | 38269| 40593| 56552| 56662| 64493| 62045| 318614|
苹果       |店面      | 43845| 40539| 44909| 55646| 56771| 64933| 306643|
苹果       |淘宝      | 42969| 43289| 48769| 58052| 58872| 59844| 311795|
苹果       |【所有渠道】|125083|124421|150230|170360|180136|186822| 937052|
香蕉       |京东      | 36879| 36981| 51748| 54801| 64936| 60688| 306033|
香蕉       |店面      | 41210| 39420| 50884| 52085| 60249| 67597| 311445|
香蕉       |淘宝      | 42468| 41955| 52780| 54971| 56504| 59213| 307891|
香蕉       |【所有渠道】|120557|118356|155412|161857|181689|187498| 925369|
【全部产品】|【所有渠道】|371723|362194|452932|480065|544242|560526|2771682|

MODEL 子句允许通过分区(PARTITION BY)和维度(DIMENSION BY)创建一个多维数组,并且通过指定规则(RULES)来操作和更新数组中单元格中的度量值(MEASURES)。其中,规则支持通配符和循环迭代,度量可以使用聚合函数和窗口函数。

MODEL 子句完整的使用姿势请参考官方文档。

以上是“Oracle中如何实现数据透视表”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网行业资讯频道!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Oracle中如何实现数据透视表

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Oracle中如何实现数据透视表

这篇文章主要介绍Oracle中如何实现数据透视表,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!使用 CASE 表达式实现数据透视表数据透视表的本质就是按照行和列的不同组合进行数据分组,然后对结果进行汇总;因此,它和数
2023-06-14

Python如何实现数据透视表

这篇文章主要为大家展示了“Python如何实现数据透视表”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Python如何实现数据透视表”这篇文章吧。用Python里的Pandas可以实现,虽然感觉
2023-06-25

access数据透视表如何做

要在Access中创建透视表,您可以按照以下步骤操作:1. 打开Access数据库并选择要在其上创建透视表的数据表。2. 在“创建”选项卡中,单击“查询设计”以打开查询设计视图。3. 在“查询设计”工具栏上,将表添加到查询设计视图中。4.
2023-10-11

wps数据透视表如何做

这篇文章主要介绍“wps数据透视表如何做”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“wps数据透视表如何做”文章能帮助大家解决问题。用wps打开所需要设置的数据表格,并选择需要设置透视表的数据。
2023-07-01

MySQL/MariaDB怎么实现数据透视表

这篇文章将为大家详细讲解有关MySQL/MariaDB怎么实现数据透视表,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。使用 CASE 表达式和分组聚合数据透视表的本质就是按照行和列的不同组合进行数据分组,
2023-06-14

Excel数据透视表如何制作

制作Excel数据透视表的步骤如下:1. 打开Excel并导入数据。确保你的数据是以表格形式排列的,并且每一列都有合适的表头。2. 选择任意一个数据单元格,然后点击Excel菜单栏中的“插入”选项卡,然后选择“数据透视表”或“透视表”。3.
2023-10-07

MySQL/MariaDB 如何实现数据透视表的示例代码

前文介绍了Oracle 中实现数据透视表的几种方法,今天我们来看看在 MySQL/MariaDB 中如何实现相同的功能。 本文使用的示例数据可以点此下载。 使用 CASE 表达式和分组聚合数据透视表的本质就是按照行和列的不同组合进行数据分组
2022-05-14

怎么使用Python+Pandas实现数据透视表

这篇文章主要介绍了怎么使用Python+Pandas实现数据透视表的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么使用Python+Pandas实现数据透视表文章都会有所收获,下面我们一起来看看吧。导入示例数
2023-07-02

excel数据透视表求和项如何设置

这篇文章主要介绍了excel数据透视表求和项如何设置的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇excel数据透视表求和项如何设置文章都会有所收获,下面我们一起来看看吧。excel数据转换成图表显示百分比:1
2023-07-02

Python中怎么实现一个透视表

本篇文章为大家展示了Python中怎么实现一个透视表,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1. 数据为帮助大家更好地理解,在讲解如何使用pivot_table( )实现透视表前,我们先导入示
2023-06-16

Java中怎么创建Excel 数据透视表

今天就跟大家聊聊有关Java中怎么创建Excel 数据透视表,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。使用工具:Free Spire.XLS for JavaJar文件导入方法方
2023-06-02

数据库的数据透视表数据源引用无效如何解决

今天小编给大家分享一下数据库的数据透视表数据源引用无效如何解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
2023-03-01

Pandas数据透视的函数如何使用

这篇文章主要介绍了Pandas数据透视的函数如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Pandas数据透视的函数如何使用文章都会有所收获,下面我们一起来看看吧。pandas.melt()melt函数
2023-07-02

Python中如何实现数据可视化

今天就跟大家聊聊有关Python中如何实现数据可视化,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。热力图热力图(Heat Map)是数据的一种矩阵表示方法,其中每个矩阵元素的值通过一
2023-06-16

excel数据透视表行标签和列标签如何设置

本篇内容主要讲解“excel数据透视表行标签和列标签如何设置”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“excel数据透视表行标签和列标签如何设置”吧!1、首先,我们进入“插入”选择“数据透视
2023-07-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录