2016-05-25 1 views
1

У меня есть таблица в Oracle 10g DB engine, которая содержит записи о сервисных операциях. Требование - рассчитать время обработки каждого запроса на обслуживание. Каждый запрос на обслуживание может генерировать несколько записей, каждый из которых представляет собой этап в этом процессе. Поэтому у меня есть стол со следующими столбцами:Как я могу группировать записи и выполнять вычисления между первой и последней записями в каждой группе с использованием Oracle SQL?

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?

+0

Что такое поле, которое определяет порядок записи, чтобы определить первые и последние записи? Мы заказываем Id, причем самым маленьким номером является «первая» запись, а наибольшее число - «последняя» запись? – Lock

+0

Ну идентификатор должен быть довольно стабильным. Я не могу придумать сценарий, когда более поздний шаг с более поздней меткой времени будет сгенерирован с более низким идентификатором. – Max

ответ

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; 
+0

Это максимальная и минимальная, он хотел первого и последнего! – sagi

+0

@sagi - Как минимальные и максимальные даты отличаются от первой и последней дат? –

+0

Возможно, это мое плохое. Максимальные и минимальные - первые и последние в терминах временной метки. – Max

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

0

Аналитическая функция. 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; 
Смежные вопросы