假设一个表tableX,如下所示:
| date | hours |
| 2014-07-02 | 10 |
| 2014-07-03 | 10 |
| 2014-07-07 | 20 |
| 2014-07-08 | 40 |
日期是'工作日' - 即没有周末或假日。
我想找到连续工作日之间的小时数增加,如下所示:
| date | hours |
| 2014-07-03 | 0 |
| 2014-07-07 | 10 |
| 2014-07-08 | 20 |
挑战在于应对差距。如果没有差距,比如
SELECT t1.date1 AS 'first day', t2.date1 AS 'second day', (t2.hours - t1.hours)
FROM tableX t1
LEFT JOIN tableX t2 ON t2.date1 = DATE_add(t1.date1, INTERVAL 1 DAY)
ORDER BY t2.date1;
会完成它,但在这种情况下这不起作用,因为2014-07-03和2014-07-07之间存在差距。
答案 0 :(得分:0)
只需使用相关的子查询。您有两个字段,因此您可以使用两个相关的子查询或带有join
的相关子查询返回到表中。这是第一个版本:
SELECT t1.date1 as `first day`,
(select t2.date1
from tableX t2
where t2.date1 > t.date1
order by t2.date asc
limit 1
) as `next day`,
(select t2.hours
from tableX t2
where t2.date1 > t.date1
order by t2.date asc
limit 1
) - t.hours
FROM tableX t
ORDER BY t.date1;
答案 1 :(得分:0)
另一种方法是按日期对数据进行排名,然后从当前工作日的小时数中减去上一个工作日的日期。
SELECT
ranked_t1.date1 date,
ranked_t1.hours - ranked_t2.hours hours
FROM
(
SELECT t.*,
@rownum := @rownum + 1 AS rank
FROM (SELECT * FROM tableX ORDER BY date1) t,
(SELECT @rownum := 0) r
) ranked_t1
INNER JOIN
(
SELECT t.*,
@rownum2 := @rownum2 + 1 AS rank
FROM (SELECT * FROM tableX ORDER BY date1) t,
(SELECT @rownum2 := 0) r
) ranked_t2
ON ranked_t2.rank = ranked_t1.rank - 1;
注意强>:
显然,tableX.date1上的索引会加快查询速度。
在上述查询中使用连接而不是相关子查询。
<强>参考强>:
答案 2 :(得分:0)
不幸的是,MySQL(尚未)具有分析功能,允许您访问数据流的“上一行”或“下一行”。但是,您可以使用以下方法复制它:
select h2.LogDate, h2.Hours - h1.Hours as Added_Hours
from Hours h1
left join Hours h2
on h2.LogDate =(
select Min( LogDate )
from Hours
where LogDate > h1.LogDate )
where h2.LogDate is not null;
查看here。请注意日期字段上的索引。如果该字段未编入索引,则此查询将永久使用。