Saya memiliki tabel 'idtimes' InnoDB (MySQL 5.0.22-log) dengan kolom
`id` int(11) NOT NULL,
`time` int(20) NOT NULL, [...]
dengan kunci unik majemuk
UNIQUE KEY `id_time` (`id`,`time`)
sehingga ada beberapa stempel waktu per id dan beberapa id per stempel waktu.
Saya mencoba mengatur kueri di mana saya mendapatkan semua entri plus waktu berikutnya yang lebih besar untuk setiap entri, jika ada, maka itu harus kembali misalnya:
+-----+------------+------------+
| id | time | nexttime |
+-----+------------+------------+
| 155 | 1300000000 | 1311111111 |
| 155 | 1311111111 | 1322222222 |
| 155 | 1322222222 | NULL |
| 156 | 1312345678 | 1318765432 |
| 156 | 1318765432 | NULL |
+-----+------------+------------+
Saat ini saya sejauh ini:
SELECT l.id, l.time, r.time FROM
idtimes AS l LEFT JOIN idtimes AS r ON l.id = r.id
WHERE l.time < r.time ORDER BY l.id ASC, l.time ASC;
tapi tentu saja ini mengembalikan semua baris dengan r.time> l.time dan tidak hanya yang pertama ...
Saya kira saya perlu subselect seperti
SELECT outer.id, outer.time,
(SELECT time FROM idtimes WHERE id = outer.id AND time > outer.time
ORDER BY time ASC LIMIT 1)
FROM idtimes AS outer ORDER BY outer.id ASC, outer.time ASC;
tapi saya tidak tahu bagaimana merujuk ke waktu saat ini (saya tahu di atas bukan SQL yang valid).
Bagaimana saya melakukan ini dengan satu query (dan saya lebih suka untuk tidak menggunakan @variables yang bergantung pada melangkah melalui tabel satu baris pada satu waktu dan mengingat nilai terakhir)?
is null
dan bergabung dengan i3where not exists (select 1 from itimes i3 where [same clause])
, maka kode akan lebih mencerminkan apa yang ingin kita ungkapkan.Sebelum menyajikan solusi, saya harus perhatikan itu tidak cantik. Akan jauh lebih mudah jika Anda memiliki beberapa
AUTO_INCREMENT
kolom di meja Anda (bukan?)Penjelasan:
(id, time)
kombinasi (yang juga dikenal unik).(l.id, l.time)
, dapatkan yang pertamar.time
lebih besar daril.time
. Ini terjadi dengan pertama memesanr.time
s viaGROUP_CONCAT(r.time ORDER BY r.time)
, dengan mengiris token pertama melaluiSUBSTRING_INDEX
.Semoga sukses, dan, jangan berharap kinerja yang baik jika tabel ini besar.
sumber
Anda juga bisa mendapatkan apa yang Anda inginkan dari
min()
danGROUP BY
tanpa pilih dalam:Saya hampir akan bertaruh sejumlah besar uang bahwa pengoptimal mengubah ini menjadi hal yang sama dengan jawaban Erwin Smout, dan masih bisa diperdebatkan apakah itu lebih jelas, tetapi ada untuk kelengkapannya ...
sumber