行のタイムスタンプと同じ値Duration
の前の行の違いである単一のクエリで、このテーブルに設定する方法に頭を悩ませようとしています。SkillTargetID
似たような質問をいくつか見つけましたが (これは特に役に立ちました)、たとえば、月の値に基づいて 2 行目がどれくらい離れているかを予測することができました。私のデータの各行について、その「姉妹」行はそれに隣接している場合もあれば、隣接していない場合もあります。
この例のテーブルの縮小版を次に示します。
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
は常に前の行以上になります。SkillTargetID
同じ値を持つ異なる値の順序はUTC_DateTime
予測できず、多くの行で同じUTC_DateTime
およびSkillTargetID
(16 と 17 など) になります。
これまでに思いついた最善の試みには、前に関連付けられた行が存在する場合は、それを見つけるためのサブクエリが含まれています (2 番目も選択した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);
事前に助けてくれてありがとう!