【问题标题】:How do I pivot in Oracle SQL 19如何在 Oracle SQL 19 中进行数据透视
【发布时间】:2021-03-10 16:34:31
【问题描述】:

我在 Oracle SQL 19 中有下表:

+---------+-----------+---------------------+
| job_num | job_stage |      timestamp      |
+---------+-----------+---------------------+
| job_1   | waiting   | 2020-01-28 11:51:00 |
| job_1   | waiting   | 2020-01-28 11:52:00 |
| job_1   | waiting   | 2020-01-28 11:53:00 |
| job_1   | running   | 2020-01-28 11:54:00 |
| job_1   | running   | 2020-01-28 11:55:00 |
| job_1   | running   | 2020-01-28 11:56:00 |
| job_1   | running   | 2020-01-28 11:57:00 |
| job_1   | finishing | 2020-01-28 11:58:00 |
| job_1   | finishing | 2020-01-28 11:59:00 |
| job_2   | waiting   | 2020-01-28 11:52:00 |
| job_2   | waiting   | 2020-01-28 11:53:00 |
| job_2   | waiting   | 2020-01-28 11:54:00 |
| job_2   | waiting   | 2020-01-28 11:55:00 |
| job_2   | waiting   | 2020-01-28 11:56:00 |
| job_2   | running   | 2020-01-28 11:57:00 |
| job_2   | running   | 2020-01-28 11:58:00 |
| job_2   | running   | 2020-01-28 11:59:00 |
| job_2   | running   | 2020-01-28 12:00:00 |
| job_2   | finishing | 2020-01-28 12:01:00 |
| job_2   | finishing | 2020-01-28 12:02:00 |
| job_2   | finishing | 2020-01-28 12:03:00 |
| job_2   | finishing | 2020-01-28 12:04:00 |
+---------+-----------+---------------------+

我想通过以下方式旋转它:

+---------+---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+
| job_num |     min_waiting     |     max_waiting     |     min_running     |     max_running     |    min_finishing    |    max_finishing    |
+---------+---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+
| job_1   | 2020-01-28 11:51:00 | 2020-01-28 11:53:00 | 2020-01-28 11:54:00 | 2020-01-28 11:57:00 | 2020-01-28 11:58:00 | 2020-01-28 11:59:00 |
| job_2   | 2020-01-28 11:52:00 | 2020-01-28 11:56:00 | 2020-01-28 11:57:00 | 2020-01-28 12:00:00 | 2020-01-28 12:01:00 | 2020-01-28 12:04:00 |
+---------+---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+

更具体地说,对于每个job_num,对于每个job_stage,我想获取最小时间戳和最大时间戳。然后,我想显示每个job_num 的最小和最大时间戳。

谁能告诉我如何在 Oracle SQL 19 中有效地做到这一点?任何帮助将不胜感激!

我在 SQL 中有以下表格供您参考:

未透视表如下:

with t1 as (
            select 'job_1' as job_num
                   , 'waiting' as job_stage
                   , to_date('1/28/2020 11:51', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_1' as job_num
                   , 'waiting' as job_stage
                   , to_date('1/28/2020 11:52', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_1' as job_num
                   , 'waiting' as job_stage
                   , to_date('1/28/2020 11:53', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_1' as job_num
                   , 'running' as job_stage
                   , to_date('1/28/2020 11:54', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_1' as job_num
                   , 'running' as job_stage
                   , to_date('1/28/2020 11:55', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_1' as job_num
                   , 'running' as job_stage
                   , to_date('1/28/2020 11:56', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_1' as job_num
                   , 'running' as job_stage
                   , to_date('1/28/2020 11:57', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_1' as job_num
                   , 'finishing' as job_stage
                   , to_date('1/28/2020 11:58', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_1' as job_num
                   , 'finishing' as job_stage
                   , to_date('1/28/2020 11:59', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_2' as job_num
                   , 'waiting' as job_stage
                   , to_date('1/28/2020 11:52', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_2' as job_num
                   , 'waiting' as job_stage
                   , to_date('1/28/2020 11:53', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_2' as job_num
                   , 'waiting' as job_stage
                   , to_date('1/28/2020 11:54', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_2' as job_num
                   , 'waiting' as job_stage
                   , to_date('1/28/2020 11:55', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_2' as job_num
                   , 'waiting' as job_stage
                   , to_date('1/28/2020 11:56', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_2' as job_num
                   , 'running' as job_stage
                   , to_date('1/28/2020 11:57', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_2' as job_num
                   , 'running' as job_stage
                   , to_date('1/28/2020 11:58', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_2' as job_num
                   , 'running' as job_stage
                   , to_date('1/28/2020 11:59', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_2' as job_num
                   , 'running' as job_stage
                   , to_date('1/28/2020 12:00', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_2' as job_num
                   , 'finishing' as job_stage
                   , to_date('1/28/2020 12:01', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_2' as job_num
                   , 'finishing' as job_stage
                   , to_date('1/28/2020 12:02', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_2' as job_num
                   , 'finishing' as job_stage
                   , to_date('1/28/2020 12:03', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
            union
            select 'job_2' as job_num
                   , 'finishing' as job_stage
                   , to_date('1/28/2020 12:04', 'MM/DD/YYYY HH24:MI') as timestamp
                   from dual
                )
select *
from t1
order by job_num
, timestamp

透视表如下:

with t1 as (
            select 'job_1' as job_num
                   , to_date('1/28/2020 11:51', 'MM/DD/YYYY HH24:MI') as min_waiting
                   , to_date('1/28/2020 11:53', 'MM/DD/YYYY HH24:MI') as max_waiting
                   , to_date('1/28/2020 11:54', 'MM/DD/YYYY HH24:MI') as min_running
                   , to_date('1/28/2020 11:57', 'MM/DD/YYYY HH24:MI') as max_running
                   , to_date('1/28/2020 11:58', 'MM/DD/YYYY HH24:MI') as min_finishing
                   , to_date('1/28/2020 11:59', 'MM/DD/YYYY HH24:MI') as max_finishing                   
                   from dual
            union
            select 'job_2' as job_num
                   , to_date('1/28/2020 11:52', 'MM/DD/YYYY HH24:MI') as min_waiting
                   , to_date('1/28/2020 11:56', 'MM/DD/YYYY HH24:MI') as max_waiting
                   , to_date('1/28/2020 11:57', 'MM/DD/YYYY HH24:MI') as min_running
                   , to_date('1/28/2020 12:00', 'MM/DD/YYYY HH24:MI') as max_running
                   , to_date('1/28/2020 12:01', 'MM/DD/YYYY HH24:MI') as min_finishing
                   , to_date('1/28/2020 12:04', 'MM/DD/YYYY HH24:MI') as max_finishing                   
                   from dual
                )
select *
from t1
order by job_num

【问题讨论】:

  • 几个问题/建议:首先,“timestamp”是Oracle关键字;即使在某些情况下将其用作列名不会引发错误,但至少会令人困惑。使用其他东西,要么 ts 要么可能 timestamp_ (带下划线)。其次,为什么要对名为 TIMESTAMP 的列使用 TO_DATE?实际表中的实际数据类型是什么 - DATE 或 TIMESTAMP?不要使用与列的数据类型直接矛盾的列名。

标签: oracle oracle19c


【解决方案1】:
select job_num, w_min as min_waiting  , w_max as max_waiting,
                r_min as min_running  , r_max as max_running,
                f_min as min_finishing, f_max as max_finishing
from   t1
pivot  (min(timestamp) as min, max(timestamp) as max
            for job_stage in ('waiting' as w, 'running' as r, 'finishing' as f)
       )
order by job_num
;

【讨论】:

    【解决方案2】:
    SELECT *
    FROM   table_name
    PIVOT(
      MIN( "TIMESTAMP" ) AS min,
      MAX( "TIMESTAMP" ) AS max
      FOR job_stage IN (
        'waiting' AS waiting,
        'running' AS running,
        'finishing' AS finishing
      )
    )
    

    或:

    SELECT job_num,
           MIN( CASE job_stage WHEN 'waiting' THEN "TIMESTAMP" END ) AS waiting_min,
           MAX( CASE job_stage WHEN 'waiting' THEN "TIMESTAMP" END ) AS waiting_max,
           MIN( CASE job_stage WHEN 'running' THEN "TIMESTAMP" END ) AS running_min,
           MAX( CASE job_stage WHEN 'running' THEN "TIMESTAMP" END ) AS running_max,
           MIN( CASE job_stage WHEN 'finishing' THEN "TIMESTAMP" END ) AS finishing_min,
           MAX( CASE job_stage WHEN 'finishing' THEN "TIMESTAMP" END ) AS finishing_max
    FROM   table_name
    GROUP BY job_num
    

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

    作业_NUM | WAITING_MIN | WAITING_MAX | RUNNING_MIN | RUNNING_MAX | FINISHING_MIN | FINISHING_MAX :-------- | :----------------- | :----------------- | :----------------- | :----------------- | :----------------- | :----------------- 工作_2 | 2020-01-28 11:52:00 | 2020-01-28 11:56:00 | 2020-01-28 11:57:00 | 2020-01-28 12:00:00 | 2020-01-28 12:01:00 | 2020-01-28 12:04:00 工作_1 | 2020-01-28 11:51:00 | 2020-01-28 11:53:00 | 2020-01-28 11:54:00 | 2020-01-28 11:57:00 | 2020-01-28 11:58:00 | 2020-01-28 11:59:00

    db小提琴here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-10
      • 2011-06-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多