我有以下记录集:
+------------------------------------------+
| ID | DateTimeValue | UsedMinutes |
| 1 | 2016-01-01 00:00:00 | 30 |
| 2 | 2016-01-01 00:00:00 | 45 |
| 3 | 2016-01-01 00:00:00 | 20 |
| 4 | 2016-02-02 00:00:00 | 30 |
| 5 | 2016-02-02 00:00:00 | 60 |
+------------------------------------------+
我想将它们转换为:
+------------------------------------------+
| ID | DateTimeValue | UsedMinutes |
| 1 | 2016-01-01 00:00:00 | 30 |
| 2 | 2016-01-01 00:30:00 | 45 |
| 3 | 2016-01-01 01:15:00 | 20 |
| 4 | 2016-02-02 00:00:00 | 30 |
| 5 | 2016-02-02 00:30:00 | 60 |
+------------------------------------------+
因此,对于每个日期,时间值应根据先前的记录及其“使用的分钟数”字段递增。我的实际记录集有数千条记录,因此不能手动修改。
是否可以使用(单个)MySQL查询执行此操作?
答案 0 :(得分:1)
我认为这将解决您的问题
mysql> select * from TRE;
+------+---------------+-------------+
| ID | DateTimeValue | UsedMinutes |
+------+---------------+-------------+
| 1 | 2016-01-01 | 30 |
| 2 | 2016-01-01 | 45 |
| 3 | 2016-01-01 | 20 |
| 4 | 2016-02-02 | 30 |
| 5 | 2016-02-02 | 60 |
+------+---------------+-------------+
5 rows in set (0.00 sec)
mysql> select TRE.*,@curRank := @curRank + UsedMinutes as SUM_time from TRE,(SELECT @curRank := 0) r ORDER BY ID;
+------+---------------+-------------+----------+
| ID | DateTimeValue | UsedMinutes | SUM_time |
+------+---------------+-------------+----------+
| 1 | 2016-01-01 | 30 | 30 |
| 2 | 2016-01-01 | 45 | 75 |
| 3 | 2016-01-01 | 20 | 95 |
| 4 | 2016-02-02 | 30 | 125 |
| 5 | 2016-02-02 | 60 | 185 |
+------+---------------+-------------+----------+
5 rows in set (0.03 sec)
mysql> select DATE_ADD(DateTimeValue, INTERVAL @curRank := @curRank + UsedMinutes MINUTE) from TRE,(SELECT @curRank := 0) r ORDER BY ID;
+-----------------------------------------------------------------------------+
| DATE_ADD(DateTimeValue, INTERVAL @curRank := @curRank + UsedMinutes MINUTE) |
+-----------------------------------------------------------------------------+
| 2016-01-01 00:30:00 |
| 2016-01-01 01:15:00 |
| 2016-01-01 01:35:00 |
| 2016-02-02 02:05:00 |
| 2016-02-02 03:05:00 |
+-----------------------------------------------------------------------------+
5 rows in set (0.05 sec)
答案 1 :(得分:1)
你可以尝试一下:
SELECT
t.ID,
t.expectedTime,
t.usedMin
FROM
(
SELECT
ID,
IF(@currentDateTime <> DateTimeValue, @runningTime :='0000-00-00 00:00:00' , 1) resetting,
IF(@runningTime = '0000-00-00 00:00:00', DateTimeValue, @runningTime) AS expectedTime,
@minuteToAddNext := UsedMinutes AS usedMin,
@currentDateTime := DateTimeValue AS previousDateTime,
@runningTime := IF(@runningTime = '0000-00-00 00:00:00', DateTimeValue + INTERVAL UsedMinutes MINUTE , @runningTime + INTERVAL UsedMinutes MINUTE) AS nextRowsValue
FROM
datetimetable
CROSS JOIN (
SELECT
@currentDateTime := '0000-00-00 00:00:00',
@minuteToAddNext := 0,
@runningTime := '0000-00-00 00:00:00'
) AS var
ORDER BY DateTimeValue
) AS t;
WORKING DEMO 输出4列(一个额外的)
UPDATED WORKING DEMO 输出3列符合您的要求
<强>解释强>
扫描每一行时,将UsedMinutes
值存储在名为@minuteToAddNext
的变量中,如查询中所示:
@minuteToAddNext := UsedMinutes
在扫描下一行时,只有@minuteToAddNext
值从同一DateTimeValue
保存时,您的第一项任务才是将@minuteToAddNext
值添加到dateTimeValue
。这在查询中翻译如下:
DateTimeValue + INTERVAL IF(@currentDateTime = DateTimeValue, @minuteToAddNext , 0) MINUTE AS updatedDteTimeValue
看,如果上一行@currentDateTime = current row's DateTimeValue
,那么您将从@minuteToAddNext
获得IF
。 (意思相同dateTimeValue
)。
否则IF
将返回0
。所以,DateTimeValue + INTERVAL 0 MINUTE = DateTimeValue
修改强>
为了使用上述选择查询中生成的datetime
值更新表,您需要运行以下查询:
UPDATE datetimetable DT
INNER JOIN
(
SELECT
ID,
IF(@currentDateTime <> DateTimeValue, @runningTime :='0000-00-00 00:00:00' , 1) resetting,
IF(@runningTime = '0000-00-00 00:00:00', DateTimeValue, @runningTime) AS expectedTime,
@minuteToAddNext := UsedMinutes AS usedMin,
@currentDateTime := DateTimeValue AS previousDateTime,
@runningTime := IF(@runningTime = '0000-00-00 00:00:00', DateTimeValue + INTERVAL UsedMinutes MINUTE , @runningTime + INTERVAL UsedMinutes MINUTE) AS nextRowsValue
FROM
datetimetable
CROSS JOIN (
SELECT
@currentDateTime := '0000-00-00 00:00:00',
@minuteToAddNext := 0,
@runningTime := '0000-00-00 00:00:00'
) AS var
ORDER BY DateTimeValue
) AS t
ON DT.ID = t.ID
SET DT.DateTimeValue = t.expectedTime;