我有一个示例表(table_name:track_task),如下所示:
task_id stage log_date
----------------------------------------
3 1 2011-06-01 08:36:21
9 1 2011-06-03 12:35:47
3 2 2011-06-05 14:25:42
21 1 2011-06-11 13:03:34
9 2 2011-06-11 15:25:57
3 3 2011-06-12 10:16:09
21 2 2011-06-15 15:30:29
3 4 2011-06-22 15:34:33
21 3 2011-06-23 12:53:49
9 4 2011-06-25 16:25:08
当应用程序代码中的某个操作进行任务阶段时,将自动填充上述数据。阶段从1到4运行。但是,由于某些逻辑,任务可能会跳过第3阶段。但是所有任务都在第4阶段结束。可能的任务路径是这样的:
(1,2,3,4) / (1,2,4) - Completed tasks
(1,2,3) / (1,2) - In progress tasks
我需要查询并检索一个报告,该报告显示任务在给定时间的每个阶段所花费的时间(以天为单位)。到目前为止,我已经提出了以下查询:
SELECT z.task_id, a.log_date begin_date, d.log_date end_date,
DATEDIFF( b.log_date, a.log_date ) step1_days,
DATEDIFF( c.log_date, b.log_date ) step2_days,
DATEDIFF( d.log_date, c.log_date ) step3_days,
DATEDIFF( d.log_date, a.log_date ) cycle_days
FROM track_task z
LEFT JOIN track_task a ON ( z.task_id = a.task_id AND a.staging_id =1 )
LEFT JOIN track_task b ON ( z.task_id = b.task_id AND b.staging_id =2 )
LEFT JOIN track_task c ON ( z.task_id = c.task_id AND c.staging_id =3 )
LEFT JOIN track_task d ON ( z.task_id = d.task_id AND d.staging_id =4 )
GROUP BY z.oppty_id
导出如下的结果集:
task_id begin_date end_date step1_days step2_days step3_days cycle_days
-------------------------------------------------------------------------------
3 2011-06-01 2011-06-22 4 7 10 21
9 2011-06-03 2011-06-25 8 NULL NULL 22
21 2011-06-11 NULL 4 8 NULL NULL
这是一个很好的方法,还是有更好的方法?如何将NULL值报告为零?如何为正在进行的任务检索end_date?
答案 0 :(得分:0)
这看起来我将如何做这样的事情,假设每个stage
只使用一个task
的实例(如果没有,你需要更多的工作,在定义你的要求和编写查询。)
要使null
显示为0
,请使用COALESCE()
功能:
SELECT z.task_id, COALESCE(DATEDIFF(b.log_date, a.log_date), 0) as step1_days
答案 1 :(得分:0)
没有建议改善问题的一般方法。但是,您可以使用MySQL的COALESCE函数http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_coalesce将NULL值报告为0(或其他任何事情)。
Coalesce将列表作为输入并返回第一个非空值。
例如:
SELECT z.task_id, a.log_date begin_date, d.log_date end_date,
COALESCE(DATEDIFF( b.log_date, a.log_date ),0) step1_days,
COALESCE(DATEDIFF( c.log_date, b.log_date ),0) step2_days,
...
如果0
或step1_days
为step2_days
,则会返回NULL
。
答案 2 :(得分:0)
关于第三个问题,对查询进行以下编辑可以解决问题。
SELECT z.task_id, a.log_date begin_date, e.log_date end_date,
COALESCE(DATEDIFF( b.log_date, a.log_date ),0) step1_days,
COALESCE(DATEDIFF( c.log_date, b.log_date ),0) step2_days,
COALESCE(DATEDIFF( d.log_date, c.log_date ),0) step3_days,
COALESCE(DATEDIFF( d.log_date, a.log_date ),0) cycle_days
FROM track_task z
LEFT JOIN track_task a ON ( z.task_id = a.task_id AND a.staging_id =1 )
LEFT JOIN track_task b ON ( z.task_id = b.task_id AND b.staging_id =2 )
LEFT JOIN track_task c ON ( z.task_id = c.task_id AND c.staging_id =3 )
LEFT JOIN track_task d ON ( z.task_id = d.task_id AND d.staging_id =4 )
LEFT JOIN track_task e ON ( z.task_id = e.task_id AND e.staging_id IN
(
SELECT max( staging_id )
FROM z_table_trial
GROUP BY oppty_id
)
)
GROUP BY z.oppty_id