我的应用程序中有两个与跟踪作业相关的表(MySQL)。第一个表"工作"系统中记录的每个作业包含一行。这是由作业进度表支持的,该表在每次作业移动到新状态时都会跟踪添加了新行的作业的进度。也可以再次重新打开作业并将其推回到先前的状态。因此,job_progress表可以具有相同作业状态但在不同日期/时间的多个条目。
我希望能够通过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 |
+----+-----------+-----------------------+---------------------+--------------------------+--------------------------+--------------------------------+-------------------------+
以下是我的尝试:
答案 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
编辑:继续添加一些要求
看起来像是在PIVOTed输出之后。据我所知,在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
编辑:继续添加一些要求
如果您想展示尚未通过所有阶段的工作,请使用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
答案 1 :(得分: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而不是内部联接
答案 2 :(得分: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