一直試圖圍繞如何在此表中設置Duration
包括我的頭,與一個查詢,這是行的時間戳和前一行的值爲SkillTargetID
。我發現了一些類似的問題(this one特別有用),但他們都能夠預測第二行的距離,例如,基於月份值。對於我的每一行數據,其「姐妹」行可能與它相鄰,或者不相鄰。設置列之間的差值行之間的行數不確定的行之間的差異
這裏是我的表在這個例子中的簡化版本:
mysql> select * from testdur order by id;
+----+---------------+--------------+----------+
| id | SkillTargetID | UTC_DateTime | Duration |
+----+---------------+--------------+----------+
| 1 | 5000 | 1323719341 | NULL |
| 2 | 5010 | 1323719341 | NULL |
| 3 | 5000 | 1323719342 | NULL |
| 4 | 5010 | 1323719342 | NULL |
| 5 | 5000 | 1323719343 | NULL |
| 6 | 5055 | 1323719345 | NULL |
| 7 | 5010 | 1323719350 | NULL |
| 8 | 5010 | 1323719441 | NULL |
| 9 | 5010 | 1323719444 | NULL |
| 10 | 5000 | 1323719445 | NULL |
| 11 | 5055 | 1323719445 | NULL |
| 12 | 5060 | 1323719445 | NULL |
| 13 | 5000 | 1323719445 | NULL |
| 14 | 5010 | 1323719445 | NULL |
| 15 | 5060 | 1323719446 | NULL |
| 16 | 5000 | 1323719460 | NULL |
| 17 | 5000 | 1323719460 | NULL |
| 18 | 5060 | 1323719500 | NULL |
+----+---------------+--------------+----------+
該表中的基礎數據符合此規則:當id
有序的UTC_DateTime
值將始終大於或等於到上一行,如這個示例數據所示。具有相同UTC_DateTime
的不同SkillTargetID
值的順序不可預測,並且許多行將具有相同的UTC_DateTime
和SkillTargetID
(如16和17)。
我想出了迄今爲止最好的嘗試包括子查詢找到以前的相關行,如果存在的話(我也選擇了第二UTC_DateTime
所以你可以看到什麼是被減去):
SELECT
t.id,
t.SkillTargetID,
t.UTC_DateTime,
t2.UTC_DateTime AS UTC_DateTime2,
(CASE WHEN t2.UTC_DateTime IS NULL THEN 0 ELSE t.UTC_DateTime - t2.UTC_DateTime END) AS Duration
FROM testdur t LEFT JOIN testdur t2
ON t.SkillTargetID = t2.SkillTargetID
AND t2.id = (
SELECT id FROM testdur
WHERE SkillTargetID = t.SkillTargetID AND id < t.id
ORDER BY id DESC
LIMIT 1)
ORDER BY t.id;
+----+---------------+--------------+---------------+----------+
| id | SkillTargetID | UTC_DateTime | UTC_DateTime2 | Duration |
+----+---------------+--------------+---------------+----------+
| 1 | 5000 | 1323719341 | NULL | 0 |
| 2 | 5010 | 1323719341 | NULL | 0 |
| 3 | 5000 | 1323719342 | 1323719341 | 1 |
| 4 | 5010 | 1323719342 | 1323719341 | 1 |
| 5 | 5000 | 1323719343 | 1323719342 | 1 |
| 6 | 5055 | 1323719345 | NULL | 0 |
| 7 | 5010 | 1323719350 | 1323719342 | 8 |
| 8 | 5010 | 1323719441 | 1323719350 | 91 |
| 9 | 5010 | 1323719444 | 1323719441 | 3 |
| 10 | 5000 | 1323719445 | 1323719343 | 102 |
| 11 | 5055 | 1323719445 | 1323719345 | 100 |
| 12 | 5060 | 1323719445 | NULL | 0 |
| 13 | 5000 | 1323719445 | 1323719445 | 0 |
| 14 | 5010 | 1323719445 | 1323719444 | 1 |
| 15 | 5060 | 1323719446 | 1323719445 | 1 |
| 16 | 5000 | 1323719460 | 1323719445 | 15 |
| 17 | 5000 | 1323719460 | 1323719460 | 0 |
| 18 | 5060 | 1323719500 | 1323719446 | 54 |
+----+---------------+--------------+---------------+----------+
很明顯,像這樣的UPDATE會隨着這個表的增長而變得非常快。這是所有我能想出來之前圍繞回圈:
UPDATE testdur t SET t.Duration = t.UTC_DateTime - (
SELECT UTC_DateTime FROM testdur
WHERE SkillTargetID = t.SkillTargetID AND id < t.id
ORDER BY id DESC LIMIT 1);
ERROR 1093 (HY000): You can't specify target table 't' for update in FROM clause
我還有什麼其他的選擇?
下面是我用的測試數據:
CREATE TABLE `testdur` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`SkillTargetID` int(10) unsigned NOT NULL,
`UTC_DateTime` int(10) unsigned NOT NULL,
`Duration` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO testdur (SkillTargetID,UTC_DateTime) VALUES (5000,1323719341),(5010,1323719341),(5000,1323719342),(5010,1323719342),(5000,1323719343),(5055,1323719345),(5010,1323719350),(5010,1323719441),(5010,1323719444),(5000,1323719445),(5055,1323719445),(5060,1323719445),(5000,1323719445),(5010,1323719445),(5060,1323719446),(5000,1323719460),(5000,1323719460),(5060,1323719500);
獎金 - 是否有可能做到這一點,同時插入新的多行數據,如果它包括有序id
了嗎?如期間:
INSERT INTO testdur (id,SkillTargetID,UTC_DateTime) VALUES
(19,5010,1323719505),
(20,5055,1323719510);
感謝您提前幫忙!
我最後做的大部分的這個代碼,而不是SQL,但是喲你的想法確實奏效 - 我測試了它。不過,我可能會將這個想法用於其他方面。感謝您抽出寶貴的時間。 – aparker 2012-04-25 20:18:04