У меня есть отношение parent-child для следующих таблиц:
CREATE TABLE 'pages' (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NULL,
PRIMARY KEY ( id )
)
CREATE TABLE 'pageObjects' (
id INT NOT NULL AUTO_INCREMENT,
object TEXT NULL,
lastChanged TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL,
fkPageId int NOT NULL,
PRIMARY KEY ( id )
)
pages
имеют отношение one: many к pageObjects
.
Всякий раз, когда записи pageObjects
подключенные к одной странице, превышают 10, все записи, отредактированные в прошлом и превышающие 10, должны быть удалены.
Я хотел сделать это в одном запросе, но я не могу понять это...
Вот как далеко я получил:
DELETE
FROM pageObjects
WHERE id NOT IN (
SELECT po.id, po.fkPageId FROM (
SELECT objects.fkPageId FROM (
SELECT COUNT(*) as count, fkPageId
FROM pageObjects
GROUP BY fkPageId
) objects
WHERE count > 10
) AS page
JOIN pageObjects po
ON page.fkPageId = po.fkPageId
AND po.lastChanged < (
SELECT MIN(lastChanged )
FROM pageObjects
WHERE fkPageId = po.fkPageId
GROUP BY fkPageId
ORDER BY lastChanged DESC
LIMIT 10
)
)
К сожалению, бит LIMIT в нижнем подзапросе не работает так, как я хочу, потому что функция MIN() должна применяться после того, как применяется LIMIT.
Поэтому я пробовал:
DELETE
FROM pageObjects
WHERE id NOT IN (
SELECT po.id, po.fkPageId FROM (
SELECT objects.fkPageId FROM (
SELECT COUNT(*) as count, fkPageId
FROM pageObjects
GROUP BY fkPageId
) objects
WHERE count > 10
) AS page
JOIN pageObjects po
ON page.fkPageId = po.fkPageId
AND po.lastChanged < (
SELECT MIN(lastChanged)
FROM (
SELECT lastChanged
FROM pageObjects
WHERE fkPageId = po.fkPageId
GROUP BY fkPageId
ORDER BY lastChanged DESC
LIMIT 10
)
)
)
Но это невозможно, потому что po.fkPageId недоступен в подзапросе подзапроса.
Есть ли способ сделать это вот так?
Вы можете сделать это достаточно просто, посчитав количество последних записей для каждого идентификатора:
DELETE FROM pageObjects
WHERE id IN (
SELECT id FROM pageObjects po
WHERE (
SELECT count(id)
FROM pageObjects po2
WHERE po2.fkPageId = po.fkPageId
AND po2.lastChanged > po.lastChanged
) > 10
)
Проверьте, что возвращает выбор: http://www.sqlfiddle.com/#!9/f5218f/1/0