сложная группировка с использованием SQL - PullRequest
0 голосов
/ 11 мая 2018

Вот то, над чем я работаю, и я не могу найти ответы на вопросы, как это сделать. Моя таблица выглядит так:

id | Status | Assigned | workflow_Id | Date     |
------------------------------------------------
1  |Open    | John     | 123       |12-02-2018
------------------------------------------------
2  |Resp    | John     | 123       |13-02-2018
------------------------------------------------
3  |Open    | John     | 123       |14-02-2018
------------------------------------------------
4  |Resp    | John     | 123       |16-02-2018
------------------------------------------------

Идентификатор рабочего процесса - уникальный ключ. Будет несколько идентификаторов, назначенных одному рабочему процессу. Здесь Джон открывает рабочий процесс и отвечает на него. Снова, может быть что-то еще, что он открывает и отвечает. Я пытаюсь рассчитать среднее время обработки каждого ответа. Мои конечные данные должны выглядеть примерно так:

Assigned |Workflow_id | Open Date  | Resp Date  | Avg_Handle_Duration |
-----------------------------------------------------------------------
john     | 123        | 12-02-2018 | 13-02-2018 | 1 day  |
john     | 123        | 14-02-2018 | 16-02-2018 | 2 days |

РЕДАКТИРОВАТЬ: я использую Postgres. Извините за упущение этой детали.

Ответы [ 4 ]

0 голосов
/ 11 мая 2018

Вам нужна условная агрегация, но проблема в том, что у вас нет второго ключа для нее. Один из способов - использовать этот ключ, используя row_number() и арифметику:

select assigned, workflow_id, 
       max(case when Status = 'Open' then date end) as OpenDate,
       max(case when Status = 'Resp' then date end) as RespDate,
       < however your database manages date differences 
from (select t.*,
             row_number() over (order by date) as seqnum
      from t
     ) t
group by assigned, workflow_id, floor( (seqnum - 1) / 2);

Тем не менее, это предполагает, что записи open / resp строго чередуются. Если это не так, то вам следует задать еще один вопрос с более подробным объяснением, правильным тегом базы данных и лучшими образцами данных.

0 голосов
/ 11 мая 2018

Это SQL Server Solution (не указана СУБД) с использованием коррелированных подзапросов.

Другие продукты СУБД будут иметь другой синтаксис DATEDIFF

SELECT  a.Assigned,
        a.workflow_Id,
        a.Date AS OpenDate,
        (SELECT TOP 1 Date FROM Workflow WHERE Date > a.Date AND Status = 'Resp' ORDER BY Date) AS RespDate,
        DATEDIFF(day,a.Date,(SELECT TOP 1 Date FROM Workflow WHERE Date > a.Date AND Status = 'Resp' AND Assigned = a.Assigned AND workflow_Id = a.workflow_Id ORDER BY Date)) AS Avg_Handle_Duration 
FROM    Workflow a
WHERE   Status = 'Open'

РЕДАКТИРОВАТЬ - Вы указали его Postgres, поэтому попробуйте следующее

SELECT  a.Assigned,
        a.workflow_Id,
        a.Date AS OpenDate,
        (SELECT  Date FROM Workflow WHERE Date > a.Date AND Status = 'Resp' ORDER BY Date LIMIT 1) AS RespDate,
        DATE_PART('day',(SELECT Date FROM Workflow WHERE Date > a.Date AND Status = 'Resp' AND Assigned = a.Assigned AND workflow_Id = a.workflow_Id ORDER BY Date LIMIT 1)::date) -DATE_PART('day',a.Date::date) AS Avg_Handle_Duration 
FROM    Workflow a
WHERE   Status = 'Open'
0 голосов
/ 11 мая 2018

Имейте коррелированный подзапрос, чтобы найти следующий отклик каждого Open.Сделайте все это в простой таблице, чтобы просто рассчитать продолжительность:

select dt.Assigned, dt.Workflow_id, dt.OpenDate,
       dt.RespDate, dt.RespDate- dt.OpenDate as Avg_Handle_Duration 
from
(select t1.Assigned, t1.Workflow_id, t1.date as OpenDate,
        (select min(t2.date) from tablename t2
         where t2.Status = 'Resp'
           and t2.date > t1.date
           and t1.assigned = t2.assigned
           and t1.Workflow_id = t2.Workflow_id) as RespDate
 from tablename t1
 where t1.Status = 'Open') dt
0 голосов
/ 11 мая 2018

Вы хотите условное агрегирование:

select *, datediff(day, OpenDate, RespDate) as Avg_Handle_Duration
from (select Assigned, workflow_Id,
            max(case when Status  = 'Open' then Date end) as OpenDate,
            max(case when Status  = 'Resp' then Date end) as RespDate,
      from table t
      group by Assigned, workflow_Id; 
    ) t;

Использование СУБД конкретная функция даты (т.е. разница дат), которую я использовал SQL Server специфично, так как o / pне имеет СУБД с тегами.Итак, используйте соответственно.

Очень плохо для меня, потому что я неправильно понял вопрос.Что ж, если ваша СУБД имеет аналитическую функцию, вы можете использовать ее как разность.

select assigned, workflow_id, 
       max(case when Status = 'Open' then date end) as OpenDate,
       max(case when Status = 'Resp' then date end) as RespDate,
       . . .  
from (select *,
             1+(row_number() over (order by date)-1)/2 Seq
      from table
     ) t
group by assigned, workflow_id, Seq;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...