【问题标题】:ORACLE SQL: Multiple Grouping Layers and Intermediate ResultsORACLE SQL:多个分组层和中间结果
【发布时间】:2021-11-19 12:48:16
【问题描述】:

在ORACLE SQL(ORACLE 19c)中,我正在寻找一种获取下表内容的方法

...类似的结构(分组)如下:

第一列数据必须按以下方式分组:

  1. 部门
  2. JOB_START_DATE,如果 JOB_START_DATE 介于“2021-01-01”和“2021-12-31”之间
  3. JOB_DESCRIPTION(s)
  4. 姓名

在第二列中,“1”代表人们在 2021 年开始工作的时间

最后,应为每个 DEPARTMENT 组输出(底部)关于在 DEPARTMENT(2021 年)内开始的人员总和的中间结果。

截取代码以生成表格数据:

 SELECT 'Zimmer, Hans'   AS NAME,
        '1978-10-01'     AS JOB_START_DATE,
        '2021-01-31'     AS JOB_END_DATE,
        'Movie Composer' AS JOB_DESCRIPTION,
        'Score'          AS DEPARTMENT
   FROM DUAL
   
 UNION ALL
 
 SELECT 'Armstrong, Louis' AS NAME,
        '1988-06-01'       AS JOB_START_DATE,
        '2021-06-30'       AS JOB_END_DATE,
        'Jazz Musician'    AS JOB_DESCRIPTION,
        'Score'            AS DEPARTMENT
   FROM DUAL
   
 UNION ALL
 
 SELECT 'Davis, Miles'  AS NAME,
        '2011-10-01'    AS JOB_START_DATE,
        '2021-03-31'    AS JOB_END_DATE,
        'Jazz Musician' AS JOB_DESCRIPTION,
        'Music'         AS DEPARTMENT
   FROM DUAL
   
 UNION ALL
 
 SELECT 'Coltrane, John' AS NAME,
        '2015-08-01'     AS JOB_START_DATE,
        '2021-06-30'     AS JOB_END_DATE,
        'Jazz Musician'  AS JOB_DESCRIPTION,
        'Music'          AS DEPARTMENT
   FROM DUAL
   
 UNION ALL
 
 SELECT 'Cobain, Kurt'  AS NAME,
        '2021-08-01'    AS JOB_START_DATE,
        '2022-07-31'    AS JOB_END_DATE,
        'Rock Musician' AS JOB_DESCRIPTION,
        'Music'         AS DEPARTMENT
   FROM DUAL
   
 UNION ALL
 
 SELECT 'Keys, Alicia'  AS NAME,
        '2021-09-01'    AS JOB_START_DATE,
        '2022-08-31'    AS JOB_END_DATE,
        'Pop Musician'  AS JOB_DESCRIPTION,
        'Music'         AS DEPARTMENT
   FROM DUAL
   
 UNION ALL
 
 SELECT 'Tarantino, Quentin' AS NAME,
        '2021-03-01'         AS JOB_START_DATE,
        '2021-08-31'         AS JOB_END_DATE,
        'Movie Director'     AS JOB_DESCRIPTION,
        'Film'               AS DEPARTMENT
   FROM DUAL
   
 UNION ALL
 
 SELECT 'Pitt, Brad'  AS NAME,
        '1999-10-01'  AS JOB_START_DATE,
        '2021-01-26'  AS JOB_END_DATE,
        'Movie Actor' AS JOB_DESCRIPTION,
        'Film'        AS DEPARTMENT
   FROM DUAL
   
 UNION ALL
 
 SELECT 'Nolan, Christopher' AS NAME,
        '2020-05-01'         AS JOB_START_DATE,
        '2021-03-31'         AS JOB_END_DATE,
        'Movie Director'     AS JOB_DESCRIPTION,
        'Film'               AS DEPARTMENT
   FROM DUAL;

在 ORACLE SQL 中是否可以根据需要对表数据进行结构化/分组?

如果是这样,我该如何实现?

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 我不知道该怎么做才能得到我想要的输出格式。你有什么想法吗?

标签: sql oracle group-by


【解决方案1】:

您似乎希望将CUBE 与条件聚合一起使用,然后对分组集进行过滤:

SELECT name,
       job_description ,
       department,
       COUNT(CASE EXTRACT(YEAR FROM job_start_date) WHEN 2021 THEN 1 END)
         AS number_of_2021_jobs
FROM   table_name
GROUP BY
       CUBE(name, job_description, department)
HAVING GROUPING_ID(name, job_description, department) IN (0, 6)
ORDER BY
       department

对于您的样本数据,输出:

NAME JOB_DESCRIPTION DEPARTMENT NUMBER_OF_2021_JOBS
Nolan, Christopher Movie Director Film 0
Pitt, Brad Movie Actor Film 0
Tarantino, Quentin Movie Director Film 1
Film 1
Cobain, Kurt Rock Musician Music 1
Coltrane, John Jazz Musician Music 0
Davis, Miles Jazz Musician Music 0
Keys, Alicia Pop Musician Music 1
Music 2
Armstrong, Louis Jazz Musician Score 0
Zimmer, Hans Movie Composer Score 0
Score 0

注意:如果您想要同一列中的值,则连接 namejob_descriptiondepartment 列并在它们之间放置换行符。

db小提琴here

【讨论】:

  • 非常感谢!这就是我想要的。如何添加“JOB_START_DATE”列?我真的需要知道一个人究竟是什么时候开始他/她的工作的。当我在 SELECT、CUBE 和 HAVING 子句中添加 JOB_START_DATE 时,我得到一个奇怪的输出... HAVING 子句中的“IN (0,6)”是什么意思?
  • @Peter 使用MAX? db<>fiddle
  • IN (0, 6)CUBE 中确定您想要的分组集。去掉HAVING子句,就可以看到所有生成的行了;您只需要包含所有值或仅部门值的行,0th 分组集对应于所有值,6 仅对应于部门。
猜你喜欢
  • 1970-01-01
  • 2010-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多