如何使用Oracle SQL对记录进行分组并在每个组的第一个和最后一个记录之间进行计算?

时间:2016-05-25 06:13:03

标签: sql excel oracle

我在Oracle 10g数据库引擎中有一个表,其中包含服务操作的记录。要求是计算每个服务请求的处理时间。每个服务请求可以生成多个记录,每个记录表示该过程中的步骤。所以我有一个包含以下列的表:

ID
CREATED_ON
SERVICE_OPERATION
RESULT
FK_SERVICE_REQUEST_ID

其中最后一列是服务请求的标识符。

如何计算CREATED_ON标识的每个组中第一个和最后一个记录的FK_SERVICE_REQUEST_ID之间的差异?我最好不要这样做:

SELECT FK_SERVICE_REQUEST_ID, CREATED_ON, SERVICE_OPERATION, RESULT FROM TABLE ORDER BY FK_SERVICE_REQUEST_ID, ID;

并在Excel中做一些技巧?如果是这样,我怎样才能在Excel中实现这一目标?

3 个答案:

答案 0 :(得分:1)

SELECT 
    FK_SERVICE_REQUEST_ID, 
    MIN(CREATED_ON) MIN_DT, 
    MAX(CREATED_ON) MAX_DT,
    MAX(CREATED_ON)-MIN(CREATED_ON) PROC_TIME
FROM TABLE 
GROUP BY 
    FK_SERVICE_REQUEST_ID
ORDER BY 
    FK_SERVICE_REQUEST_ID;

答案 1 :(得分:0)

您可以使用ROW_NUMBER()

SELECT s.FK_SERVICE_REQUEST_ID,
       MAX(CASE WHEN s.asc_rnk = 1 THEN CREATED_ON END) as first_crt_on,
       MAX(CASE WHEN s.asc_rnk = 1 THEN SERVICE_OPERATION END) as first_srv_op,
       MAX(CASE WHEN s.desc_rnk = 1 THEN CREATED_ON END) -
       MAX(CASE WHEN s.asc_rnk = 1 THEN CREATED_ON END) as diff_dates
FROM (
    SELECT t.*,
           ROW_NUMBER() OVER(PARTITION BY t.FK_SERVICE_REQUEST_ID BY t.CREATED_ON ) as asc_rnk,
           ROW_NUMBER() OVER(PARTITION BY t.FK_SERVICE_REQUEST_ID BY t.CREATED_ON  DESC) as desc_rnk
    FROM YourTable t) s
GROUP BY s.FK_SERVICE_REQUEST_ID

我使用CREATED_ON作为订单部分,如果是其他任何列,则更改它。我还使用FK_SERVICE_REQUEST_ID列作为群组,不知道它是那个还是ID

答案 2 :(得分:0)

Analitic功能。 last_VALUE和FIRST_VALUE具有默认查询窗口RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW。在这种情况下,我们想要检查窗口中的第一行到最后一行。为实现这一目标,我添加了RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING

with tabl as (
select 1 FK_SERVICE_REQUEST_ID, sysdate -10 CREATED_ON,1  idn from dual
union 
select 1 FK_SERVICE_REQUEST_ID, sysdate -15 CREATED_ON ,2  from dual
union 
select 1 FK_SERVICE_REQUEST_ID, sysdate -20 CREATED_ON,3  from dual
union 
select 2 FK_SERVICE_REQUEST_ID, sysdate -3 CREATED_ON,4  from dual
union 
select 2 FK_SERVICE_REQUEST_ID, sysdate -5 CREATED_ON,5  from dual
union 
select 2 FK_SERVICE_REQUEST_ID, sysdate -1 CREATED_ON,6  from dual)
select FK_SERVICE_REQUEST_ID, min(last_d-first_d) from (
SELECT IDn,FK_SERVICE_REQUEST_ID, CREATED_ON
  ,FIRST_VALUE(CREATED_ON) OVER (partition by FK_SERVICE_REQUEST_ID ORDER BY CREATED_ON ASC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_d
  ,last_VALUE(CREATED_ON) OVER (partition by FK_SERVICE_REQUEST_ID ORDER BY CREATED_ON ASC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_d
  from tabl)
  group by FK_SERVICE_REQUEST_ID;