我如何在 Oracle SQL 19 中进行数据透视
How do I pivot in Oracle SQL 19
我在 Oracle SQL 19 中有以下 table:
+---------+-----------+---------------------+
| 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 SQL19 中高效地执行此操作吗?任何帮助将不胜感激!
我在SQL中有以下table供大家参考:
未旋转 table 如下:
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
旋转 table 如下:
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
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
;
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
对于您的示例数据,两者都输出:
JOB_NUM | WAITING_MIN | WAITING_MAX | RUNNING_MIN | RUNNING_MAX | FINISHING_MIN | FINISHING_MAX
:------ | :------------------ | :------------------ | :------------------ | :------------------ | :------------------ | :------------------
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_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<>fiddle here
我在 Oracle SQL 19 中有以下 table:
+---------+-----------+---------------------+
| 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 SQL19 中高效地执行此操作吗?任何帮助将不胜感激!
我在SQL中有以下table供大家参考:
未旋转 table 如下:
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
旋转 table 如下:
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
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
;
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
对于您的示例数据,两者都输出:
JOB_NUM | WAITING_MIN | WAITING_MAX | RUNNING_MIN | RUNNING_MAX | FINISHING_MIN | FINISHING_MAX :------ | :------------------ | :------------------ | :------------------ | :------------------ | :------------------ | :------------------ 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_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<>fiddle here