2014-12-01 5 views
0

У меня две таблицы (MySQL) в моем приложении, связанные с заданиями отслеживания. Первая таблица «заданий» содержит одну строку для каждого задания, записанного в системе. Это поддерживается таблицей выполнения работ, которая отслеживает ход выполнения задания с добавлением новой строки каждый раз, когда работа переходит в новое состояние. Возможно также, что задание можно снова открыть и вернуть в прежнее состояние. Поэтому таблица job_progress может иметь несколько записей для одного и того же состояния задания, но в разные даты/времени.Запрос MYSQL для получения нескольких статусов из таблицы статусов

Я хотел бы получить текущее состояние задания, получив максимальную дату для определенного состояния через таблицу jobs_progress. Я также хотел бы иметь возможность получить для каждой работы дату, когда она проходила через каждое государство. Однако я изо всех сил стараюсь сделать это с помощью SQL и буду признателен за помощь. Смотрите следующий SQLFiddle: http://sqlfiddle.com/#!2/8b27f/4

Вот что я в настоящее время:

SELECT j.* 
    , jp.job_state 
    , jp.effective_date 
    , jp.user_id 
    FROM jobs j 
    LEFT 
    JOIN jobs_progress jp 
    ON jp.job_id = j.id; 
+----+-----------+-------------+-----------+-----------------------+-----------+---------------+---------------+---------------------+---------+ 
| id | agency_id | entity_type | entity_id | job_title    | job_state | system_status | job_state  | effective_date  | user_id | 
+----+-----------+-------------+-----------+-----------------------+-----------+---------------+---------------+---------------------+---------+ 
| 1 |  123 | PROPERTY |  61 | set of keys to be cut | INVOICED | ACTIVE  | NEW   | 2014-07-08 12:27:54 |  102 | 
| 1 |  123 | PROPERTY |  61 | set of keys to be cut | INVOICED | ACTIVE  | APPROVED  | 2014-07-08 12:28:02 |  102 | 
| 1 |  123 | PROPERTY |  61 | set of keys to be cut | INVOICED | ACTIVE  | ASSIGNED  | 2014-07-08 12:29:02 |  102 | 
| 1 |  123 | PROPERTY |  61 | set of keys to be cut | INVOICED | ACTIVE  | WORK_COMPLETE | 2014-07-08 12:29:11 |  102 | 
| 1 |  123 | PROPERTY |  61 | set of keys to be cut | INVOICED | ACTIVE  | INVOICED  | 2014-07-08 12:29:27 |  102 | 
| 1 |  123 | PROPERTY |  61 | set of keys to be cut | INVOICED | ACTIVE  | ASSIGNED  | 2014-08-21 12:29:02 |  103 | 
| 1 |  123 | PROPERTY |  61 | set of keys to be cut | INVOICED | ACTIVE  | WORK_COMPLETE | 2014-08-30 12:29:11 |  103 | 
| 1 |  123 | PROPERTY |  61 | set of keys to be cut | INVOICED | ACTIVE  | INVOICED  | 2014-09-01 12:29:27 |  103 | 
+----+-----------+-------------+-----------+-----------------------+-----------+---------------+---------------+---------------------+---------+ 

Вот что я хочу:

+----+-----------+-----------------------+---------------------+--------------------------+--------------------------+--------------------------------+-------------------------+ 
| id | agency_id | job_title    | raised_date (NEW) | approved_date (APPROVED) | assigned_date (ASSIGNED) | completed_date (WORK_COMPLETE) | invoiced_date (INVOICED)| 
+----+-----------+-----------------------+---------------------+--------------------------+--------------------------+--------------------------------+-------------------------+ 
| 1 |  123 | set of keys to be cut | 2014-07-08 12:27:54 | 2014-07-08 12:28:02  | 2014-08-21 12:29:02  | 2014-08-30 12:29:11   | 2014-09-01 12:29:27  | 
+----+-----------+-----------------------+---------------------+--------------------------+--------------------------+--------------------------------+-------------------------+ 

И вот что я пробовал:

+2

SQL-Fiddle хорошо, но вы должны изменить свой вопрос, и включают в себя то, что результаты, которые вы хотите (вместе с данными выборки). –

+0

, которые являются возможными состояниями? –

+0

есть ли правильная последовательность, в которой только ваше состояние может быть изменено? –

ответ

2

Это покажет вам максимальную дату для каждого состояния, поэтому должно содержать все, что вы хотите?

select 
    j.id, 
    j.agency_id, 
    j.entity_type, 
    j.entity_id, 
    j.job_title, 
    j.system_status, 
    jp.jobstate2 job_state, 
    jp.effectivedate 
from jobs j 
inner join (select job_id,job_state jobstate2,max(effective_date) effectivedate 
      from jobs_progress 
      group by job_id,job_state) jp 
      on jp.job_id = j.id 
order by effectivedate desc 

EDIT: После еще несколько требований добавляются

Это выглядит Лик вы после выхода поворачивает. Насколько я знаю, там ISN, т простой способ сделать это в MySQL, но вы можете попробовать это, что не очень, но все же производит результат вы после:

select 
    j.id, 
    j.agency_id, 
    j.entity_type, 
    j.entity_id, 
    j.job_title, 
    j.system_status, 
    j.job_state, 
    jp_new.effectivedate raised_date, 
    jp_approved.effectivedate approved_date, 
    jp_assigned.effectivedate assigned_date, 
    jp_complete.effectivedate complete_date, 
    jp_invoiced.effectivedate invoice_date 
from jobs j 
inner join (select job_id,max(effective_date) effectivedate 
      from jobs_progress 
      where job_state = 'NEW' 
      group by job_id,job_state) jp_new 
      on jp_new.job_id = j.id 
inner join (select job_id,max(effective_date) effectivedate 
      from jobs_progress 
      where job_state = 'APPROVED' 
      group by job_id,job_state) jp_approved 
      on jp_approved.job_id = j.id 
inner join (select job_id,max(effective_date) effectivedate 
      from jobs_progress 
      where job_state = 'ASSIGNED' 
      group by job_id,job_state) jp_assigned 
      on jp_assigned.job_id = j.id 
inner join (select job_id,max(effective_date) effectivedate 
      from jobs_progress 
      where job_state = 'WORK_COMPLETE' 
      group by job_id,job_state) jp_complete 
      on jp_complete.job_id = j.id 
inner join (select job_id,max(effective_date) effectivedate 
      from jobs_progress 
      where job_state = 'INVOICED' 
      group by job_id,job_state) jp_invoiced 
      on jp_invoiced.job_id = j.id 

EDIT: После еще некоторые требования добавляются

Если вы хотите, чтобы показать работы, которые не прошли через все этапы, а затем использовать LEFT OUTER JOIN вместо INNER JOIN:

select 
    j.id, 
    j.agency_id, 
    j.entity_type, 
    j.entity_id, 
    j.job_title, 
    j.system_status, 
    j.job_state, 
    jp_new.effectivedate raised_date, 
    jp_approved.effectivedate approved_date, 
    jp_assigned.effectivedate assigned_date, 
    jp_complete.effectivedate complete_date, 
    jp_invoiced.effectivedate invoice_date 
from jobs j 
left outer join (select job_id,max(effective_date) effectivedate 
       from jobs_progress 
       where job_state = 'NEW' 
       group by job_id,job_state) jp_new 
       on jp_new.job_id = j.id 
left outer join (select job_id,max(effective_date) effectivedate 
       from jobs_progress 
       where job_state = 'APPROVED' 
       group by job_id,job_state) jp_approved 
       on jp_approved.job_id = j.id 
left outer join (select job_id,max(effective_date) effectivedate 
       from jobs_progress 
       where job_state = 'ASSIGNED' 
       group by job_id,job_state) jp_assigned 
       on jp_assigned.job_id = j.id 
left outer join (select job_id,max(effective_date) effectivedate 
       from jobs_progress 
       where job_state = 'WORK_COMPLETE' 
       group by job_id,job_state) jp_complete 
       on jp_complete.job_id = j.id 
left outer join (select job_id,max(effective_date) effectivedate 
       from jobs_progress 
       where job_state = 'INVOICED' 
       group by job_id,job_state) jp_invoiced 
       on jp_invoiced.job_id = j.id 
+0

Спасибо @StevieG. Где-то там. Это дает мне эти значения для всех заданий, которые выставляются счета в системе, мне нужно, чтобы это работало для всех статусов, и если задание не прошло ни одного из этих состояний, оно должно установить дату как NULL. –

+0

Это тоже достаточно просто - просто измените соединения с 'INNER' на' LEFT OUTER' - я снова обновлю ответ. – StevieG

+0

Это тот. Благодарю. –

0

Это поможет вам последняя дата, на которую была выставлена ​​строка. Если вам нужны все даты перехода, как вы хотите отображать их?

select jobs.*, LastEntry.effective_date 
from jobs 
INNER JOIN (SELECT job_id, MAX(effective_date) AS effective_date FROM jobs_progress WHERE job_state = 'INVOICED' GROUP BY job_id) AS LastEntry ON jobs.id = LastEntry.job_id 

Это будет показывать только то, что было выставлено на счет. Если вы хотите включить задания, которые не были выставлены на счете, используйте LEFT OUTER JOIN на производной таблице вместо внутреннего соединения.

0

вы можете получить работу с последними EFFECTIVE_DATE без суб запрос. При работе с большим количеством данных соединения будут выполняться быстрее, чем подзапросы.

-> последняя работа

SELECT jb.id, 
jb_pr1.job_state, 
jb_pr1.effective_date 
FROM 
jobs jb 
INNER JOIN jobs_progress jb_pr1 on jb_pr1.job_id = jb.id 
LEFT JOIN jobs_progress jb_pr2 
ON (jb_pr1.job_id = jb_pr2.job_id AND jb_pr1.effective_date < jb_pr2.effective_date) 
WHERE jb_pr2.effective_date IS NULL; 

SQL Скрипки Ссылка: http://sqlfiddle.com/#!2/8b27f/41