题目链接:https://leetcode-cn.com/problems/reformat-department-table/

题目

部门表 Department

+---------------+---------+

| Column Name | Type |

+---------------+---------+

| id | int |

| revenue | int |

| month | varchar |

+---------------+---------+

(id, month) 是表的联合主键。

这个表格有关于每个部门每月收入的信息。

月份(month)可以取下列值 ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]。

编写一个 SQL 查询来重新格式化表,使得新的表中有一个部门 id 列和一些对应 每个月 的收入(revenue)列。

查询结果格式如下面的示例所示:

Department 表:

+------+---------+-------+

| id | revenue | month |

+------+---------+-------+

| 1 | 8000 | Jan |

| 2 | 9000 | Jan |

| 3 | 10000 | Feb |

| 1 | 7000 | Feb |

| 1 | 6000 | Mar |

+------+---------+-------+

查询得到的结果表:

+------+-------------+-------------+-------------+-----+-------------+

| id | Jan_Revenue | Feb_Revenue | Mar_Revenue | ... | Dec_Revenue |

+------+-------------+-------------+-------------+-----+-------------+

| 1 | 8000 | 7000 | 6000 | ... | null |

| 2 | 9000 | null | null | ... | null |

| 3 | null | 10000 | null | ... | null |

+------+-------------+-------------+-------------+-----+-------------+

注意,结果表有 13 列 (1个部门 id 列 + 12个月份的收入列)。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/reformat-department-table

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解答

第一感觉就是Python或者R中的长宽表转换。

R中可以使用Reshape2包中的dcast函数进行处理。

SQL中考虑用case when进行行列转换。

本地oracle环境进行测试。

-- 创建中间表
create table temp_cwh_department
(
id int,
revenue int,
month varchar2(10)
) -- 插入测试数据
insert into temp_cwh_department values(1, 8000, 'Jan');
insert into temp_cwh_department values(2, 9000, 'Jan');
insert into temp_cwh_department values(3, 10000, 'Feb');
insert into temp_cwh_department values(1, 7000, 'Feb');
insert into temp_cwh_department values(1, 6000, 'Mar'); -- 查询
select * from temp_cwh_department -- 测试
select id,
max(case when month = 'Jan' then revenue else null end) as Jan_Revenue,
max(case when month = 'Feb' then revenue else null end) as Feb_Revenue,
max(case when month = 'Mar' then revenue else null end) as Mar_Revenue,
max(case when month = 'Apr' then revenue else null end) as Apr_Revenue,
max(case when month = 'May' then revenue else null end) as May_Revenue,
max(case when month = 'Jun' then revenue else null end) as Jun_Revenue,
max(case when month = 'Jul' then revenue else null end) as Jul_Revenue,
max(case when month = 'Aug' then revenue else null end) as Aug_Revenue,
max(case when month = 'Sep' then revenue else null end) as Sep_Revenue,
max(case when month = 'Oct' then revenue else null end) as Oct_Revenue,
max(case when month = 'Nov' then revenue else null end) as Nov_Revenue,
max(case when month = 'Dec' then revenue else null end) as Dec_Revenue
from temp_cwh_department
group by id

LeetCode提交

---- oracle ----
/* Write your PL/SQL query statement below */
select id,
max(case when month = 'Jan' then revenue else null end) as Jan_Revenue,
max(case when month = 'Feb' then revenue else null end) as Feb_Revenue,
max(case when month = 'Mar' then revenue else null end) as Mar_Revenue,
max(case when month = 'Apr' then revenue else null end) as Apr_Revenue,
max(case when month = 'May' then revenue else null end) as May_Revenue,
max(case when month = 'Jun' then revenue else null end) as Jun_Revenue,
max(case when month = 'Jul' then revenue else null end) as Jul_Revenue,
max(case when month = 'Aug' then revenue else null end) as Aug_Revenue,
max(case when month = 'Sep' then revenue else null end) as Sep_Revenue,
max(case when month = 'Oct' then revenue else null end) as Oct_Revenue,
max(case when month = 'Nov' then revenue else null end) as Nov_Revenue,
max(case when month = 'Dec' then revenue else null end) as Dec_Revenue
from Department
group by id ---- 887ms

看看解答、评论,再学习一番。

改用sum,速度快一点。

---- oracle ----
---- oracle ----
/* Write your PL/SQL query statement below */
select id,
sum(case when month = 'Jan' then revenue else null end) as Jan_Revenue,
sum(case when month = 'Feb' then revenue else null end) as Feb_Revenue,
sum(case when month = 'Mar' then revenue else null end) as Mar_Revenue,
sum(case when month = 'Apr' then revenue else null end) as Apr_Revenue,
sum(case when month = 'May' then revenue else null end) as May_Revenue,
sum(case when month = 'Jun' then revenue else null end) as Jun_Revenue,
sum(case when month = 'Jul' then revenue else null end) as Jul_Revenue,
sum(case when month = 'Aug' then revenue else null end) as Aug_Revenue,
sum(case when month = 'Sep' then revenue else null end) as Sep_Revenue,
sum(case when month = 'Oct' then revenue else null end) as Oct_Revenue,
sum(case when month = 'Nov' then revenue else null end) as Nov_Revenue,
sum(case when month = 'Dec' then revenue else null end) as Dec_Revenue
from Department
group by id ---- 603ms

利用decode进行修改,再次提交。

---- oracle ----
/* Write your PL/SQL query statement below */
select id,
sum(decode(month, 'Jan', revenue, null)) as Jan_Revenue,
sum(decode(month, 'Feb', revenue, null)) as Feb_Revenue,
sum(decode(month, 'Mar', revenue, null)) as Mar_Revenue,
sum(decode(month, 'Apr', revenue, null)) as Apr_Revenue,
sum(decode(month, 'May', revenue, null)) as May_Revenue,
sum(decode(month, 'Jun', revenue, null)) as Jun_Revenue,
sum(decode(month, 'Jul', revenue, null)) as Jul_Revenue,
sum(decode(month, 'Aug', revenue, null)) as Aug_Revenue,
sum(decode(month, 'Sep', revenue, null)) as Sep_Revenue,
sum(decode(month, 'Oct', revenue, null)) as Oct_Revenue,
sum(decode(month, 'Nov', revenue, null)) as Nov_Revenue,
sum(decode(month, 'Dec', revenue, null)) as Dec_Revenue
from Department
group by id ---- 947ms

记录一个MySQL的用法。

---- MySQL ----
# Write your MySQL query statement below
select
`id`,
max(if(`month` = 'Jan', revenue, null)) as "Jan_Revenue",
max(if(`month` = 'Feb', revenue, null)) as "Feb_Revenue",
max(if(`month` = 'Mar', revenue, null)) as "Mar_Revenue",
max(if(`month` = 'Apr', revenue, null)) as "Apr_Revenue",
max(if(`month` = 'May', revenue, null)) as "May_Revenue",
max(if(`month` = 'Jun', revenue, null)) as "Jun_Revenue",
max(if(`month` = 'Jul', revenue, null)) as "Jul_Revenue",
max(if(`month` = 'Aug', revenue, null)) as "Aug_Revenue",
max(if(`month` = 'Sep', revenue, null)) as "Sep_Revenue",
max(if(`month` = 'Oct', revenue, null)) as "Oct_Revenue",
max(if(`month` = 'Nov', revenue, null)) as "Nov_Revenue",
max(if(`month` = 'Dec', revenue, null)) as "Dec_Revenue"
from
Department
group by `id`; ---- 229ms

思考

通过case when进行判断的时候,例如:case when month = 'Jan' then revenue else null end as Jan_Revenue,会导致每一条记录产生一行,与原来表格的行数一致,因为需要通过group byid进行分组,但是分组之后一定需要一个聚合函数进行计算,此处就用max即可。

oracle中if/else功能的实现方法

1.标准的SQL规范

-- 单个if
if a = xxx then
......
end if; -- 多个条件
if a = xxx then
......
else
......
end if; -- 多个if
if a = xxx then
......
elsif a = xxx then
......
end if;
---- 测试:在oracle中不用用于select中,只能用于存储过程

2.decode函数

语法decode(value, if1, then1, if2, then2, if3, then3,..., else)

解释:如果value等于if1时,decode函数的结果返回then1,...,如果不等于任何一个if值,则返回else。

3.case when

case when a = '1' then 'xxxx'
when a = '2' then 'yyyy'
else
'zzzz'
end as column

注意点:

  • 以 case 开头,以 end 结尾;
  • 分支中 when 后跟条件,then 为显示结果;
  • else 为除此之外的默认情况,类似于高级语言程序中 switch case 的 default,可以不加;
  • end 后跟别名

LeetCode:1179.重新格式化部门表的更多相关文章

  1. 员工部门表综合查询SQL

    --数据库的表设计如下: --部门:部门编号,部门名称,地址: --员工:员工编号,员工名字,职务,管理编号,入职日期,薪资,奖金,部门编号: --创建部门表: CREATE TABLE dept( ...

  2. java数据库 JDBC操作MySQL数据库常用API 部门表和员工表 创建表 添加数据 查询数据

    package com.swift.department; import java.sql.Connection; import java.sql.PreparedStatement; import ...

  3. oracle员工表和部门表基本操作

    emp 员工表(empno 员工号/ename 员工姓名/job 工作/mgr 上级编号/hiredate 受雇日期/sal 薪金/comm 佣金/deptno 部门编号) dept 部门表(dept ...

  4. Mysql 设计超市经营管理系统,包括员工信息表(employee)和 员工部门表(department)

    互联网技术学院周测机试题(二) 一.需求分析 为进一步完善连锁超市经营管理,提高管理效率,减少管理成本,决定开发一套商品管理系统,用于日常的管理.本系统分为商品管理.员工管理.店铺管理,库存管理等功能 ...

  5. [LeetCode] Task Scheduler 任务行程表

    Given a char array representing tasks CPU need to do. It contains capital letters A to Z where diffe ...

  6. hive学习04-员工部门表综合案例

    知识点: 格式转换:cast(xxx as int) 按某列分桶某列排序,排序后打标机:例如:求每个地区工资最高的那个人的信息: ROW_NUMBER() OVER(PARTITION BY COLU ...

  7. Oracle PL/SQL块 多表查询(emp员工表、dept部门表、salgrade工资等级表)

    范例: 查询每个员工的编号,姓名,职位,工资,工资等级,部门名称 ●确定要使用的数据表 |- emp表:员工的编号.姓名.职位.工资 |- salgrade表:工资等级 |- dept表:部门名称 ● ...

  8. C#LeetCode刷题-哈希表

    哈希表篇 # 题名 刷题 通过率 难度 1 两数之和 C#LeetCode刷题之#1-两数之和(Two Sum) 42.8% 简单 3 无重复字符的最长子串   24.2% 中等 18 四数之和   ...

  9. LeetCode通关:哈希表六连,这个还真有点简单

    精品刷题路线参考: https://github.com/youngyangyang04/leetcode-master https://github.com/chefyuan/algorithm-b ...

随机推荐

  1. treeview所有节点递归解法及注意!!!!!!!!!!!!!!!!!

    好吧 我把所有之前写的都删了,只为这一句话“所有变量切记小心在递归函数内部初始化”,包括:布尔,变量i,等等.至于为什么....递归就是调用自己,你初始化以后的变量,等再次调用的时候又回来了 bool ...

  2. Qt编写数据可视化大屏界面电子看板8-调整间距

    一.前言 在数据可视化大屏界面电子看板系统中,前期为了使用目标客户机,调整间距是必不可少的工作,QMainWindow中的QDockWidget,会默认生成布局和QSplitter调整宽高大小,鼠标移 ...

  3. Redis CrackIT 入侵事件引发Linux 沦陷

    ▲针对全球6379端口的redis服务器做了扫描,结果如上图 如图开放在公网的redis的6379端口的ip总数有63443个.无密码认证的IP有43024个,在总数占比里达到67%.发现遭受到red ...

  4. Data - 大数据生态圈

    本文内容来自网络,对原文内容和格式做了细微调整,并配图以便阅读理解. 如想查看初始信息,请点击原文. 00 引言 大数据本身是个很宽泛的概念,Hadoop生态圈(或者泛生态圈)基本上都是为了处理超过单 ...

  5. Python3 Selenium自动化web测试 ==> 第十一节 WebDriver高级应用 -- 显示等待 + 二次封装

    学习目的: 掌握显示等待 掌握二次封装 正式步骤: step1:显示等待的代码示例 # -*- coding:utf-8 -*- from selenium import webdriver from ...

  6. (IStool)软件打包时当文件存在时不覆盖文件(配置文件)

    需求:程序实际使用过程中有些配置信息是需要用户手动配置的,不同客户使用配置信息也不同,所以软件发布前需要考虑这个问题,覆盖安装时需要忽略这些配置文件 实现:当对应的目录下由此文件的时候不覆盖此文件 [ ...

  7. Anaconda中安装Cascade RCNN(Detectron)的若干问题

    安装参考https://github.com/zhaoweicai/Detectron-Cascade-RCNN/blob/master/INSTALL.md 1.对于在 python detectr ...

  8. 机器学习实战笔记——KNN

    机器学习实战——读书笔记 书籍奉上

  9. Ubuntu下Iptables的简单运用,开放/关闭端口,禁止/允许IP或IP段访问...

    首先添加规则有两个参数:-A和-I,其中-A是添加到规则的末尾:-I可以插入到指定位置,没有指定位置的话默认插入到规则的首部,由于匹配规则是从上往下,依次查找的,可能出现配置的规则冲突导致后续的规则不 ...

  10. Nuxt.js入门学习

    Nuxt.js简单的说是Vue.js的通用框架,最常用的就是用来作SSR(服务器端渲染).再直白点说,就是Vue.js原来是开发SPA(单页应用)的,但是随着技术的普及,很多人想用Vue开发多页应用, ...