Die folgende Tabelle hat für meinen Geschmack zu viele Subselects, aber sie erzeugt das gewünschte Ergebnis in MySQL, solange jedes Tick und jede Refid mindestens einmal separat in der Tabelle vorkommt.
Beginnen Sie mit einer Abfrage, die jedes Paar von tick und refid erzeugt. Im Folgenden wird die Tabelle verwendet, um die Paare zu generieren. Wenn also ein Tick nie in der zugrunde liegenden Tabelle auftaucht, wird er auch in den generierten Paaren fehlen. Das Gleiche gilt für refid, obwohl die Einschränkung "Alle refids haben Werte bei tick=1" sicherstellen sollte, dass letzteres nicht passiert.
SELECT tick, refid FROM
(SELECT refid FROM chadwick WHERE tick=1) AS r
JOIN
(SELECT DISTINCT tick FROM chadwick) AS t
Erzeugen Sie auf diese Weise jedes fehlende Tick- und Refid-Paar zusammen mit dem größten Tick, der in der Tabelle existiert, indem Sie Refid und θ gleichsetzen. ≥ -Anschluss an die Zecke. Gruppierung nach dem erzeugten Tick, refid, da nur eine Zeile für jedes Paar gewünscht ist. Der Schlüssel zum Herausfiltern vorhandener tick, refid-Paare ist die HAVING
Klausel. Streng genommen können Sie die Klausel weglassen HAVING
; die daraus resultierende Abfrage gibt vorhandene Zeilen mit ihren vorhandenen Werten zurück.
SELECT tr.tick, tr.refid, MAX(c.tick) AS ctick
FROM
(SELECT tick, refid FROM
(SELECT refid FROM chadwick WHERE tick=1) AS r
JOIN
(SELECT DISTINCT tick FROM chadwick) AS t
) AS tr
JOIN chadwick AS c ON tr.tick >= c.tick AND tr.refid=c.refid
GROUP BY tr.tick, tr.refid
HAVING tr.tick > MAX(c.tick)
Ein letzter Select aus der obigen Tabelle als Sub-Select, verbunden mit der ursprünglichen Tabelle, um den Wert für den angegebenen ctick zu erhalten, gibt die neuen Zeilen für die Tabelle zurück.
INSERT INTO chadwick
SELECT missing.tick, missing.refid, c.value
FROM (SELECT tr.tick, tr.refid, MAX(c.tick) AS ctick
FROM
(SELECT tick, refid FROM
(SELECT refid FROM chadwick WHERE tick=1) AS r
JOIN
(SELECT DISTINCT tick FROM chadwick) AS t
) AS tr
JOIN chadwick AS c ON tr.tick >= c.tick AND tr.refid=c.refid
GROUP BY tr.tick, tr.refid
) AS missing
JOIN chadwick AS c ON missing.ctick = c.tick AND missing.refid=c.refid
;
Leistung auf dem Mustertisch, zusammen mit (tick, refid)
y (refid, tick)
Indizes:
+----+-------------+------------+-------+-------------------+----------+---------+----------+------+---------------------------------+
| id | select\_type | table | type | possible\_keys | key | key\_len | ref | rows | Extra |
+----+-------------+------------+-------+-------------------+----------+---------+----------+------+---------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 3 | |
| 1 | PRIMARY | c | ALL | tick\_ref,ref\_tick | NULL | NULL | NULL | 6 | Using where; Using join buffer |
| 2 | DERIVED | <derived3> | ALL | NULL | NULL | NULL | NULL | 9 | Using temporary; Using filesort |
| 2 | DERIVED | c | ref | tick\_ref,ref\_tick | ref\_tick | 5 | tr.refid | 1 | Using where; Using index |
| 3 | DERIVED | <derived4> | ALL | NULL | NULL | NULL | NULL | 3 | |
| 3 | DERIVED | <derived5> | ALL | NULL | NULL | NULL | NULL | 3 | Using join buffer |
| 5 | DERIVED | chadwick | index | NULL | tick\_ref | 10 | NULL | 6 | Using index |
| 4 | DERIVED | chadwick | ref | tick\_ref | tick\_ref | 5 | | 2 | Using where; Using index |
+----+-------------+------------+-------+-------------------+----------+---------+----------+------+---------------------------------+
Wie ich schon sagte, zu viele Unterauswahlen. Eine temporäre Tabelle kann Abhilfe schaffen.
Zur Überprüfung auf fehlende Zecken:
SELECT clo.tick+1 AS missing_tick
FROM chadwick AS chi
RIGHT JOIN chadwick AS clo ON chi.tick = clo.tick+1
WHERE chi.tick IS NULL;
Dies führt zu mindestens einer Zeile, deren Tick gleich 1 + dem größten Tick in der Tabelle ist. Der größte Wert in diesem Ergebnis kann also ignoriert werden.