我有一个像这样的MySql表,
Session_Id Subscriber_Id Status ------------------------------- abc 1234 Started bcd 1235 Started bcd 1235 Finished
我需要删除状态为“已启动”的行,只有后跟“已完成”。这是一张很大的表,所以我一次会删除1000条记录。
我读了一些类似的帖子, Multiple-table DELETE LIMIT, DELETE FROM `table` AS `alias` ... WHERE `alias`.`column` ... why syntax error?
并尝试了以下查询,
mysql> delete a.* from FSESSION as a, FSESSION as b where a.status='Started' and b.status='Finished' and a.session_id=b.session_id limit 1000;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'limit 1000' at line 1 ----> If I remove 'limit' this works
mysql> DELETE FROM v USING `FSESSION` AS v WHERE status = 'Started' and exists(select 0 from FSESSION t where t.status='Finished' and v.session_id=t.session_id) limit 1000;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'limit 1000' at line 1 ---->
即使删除限制也不起作用。
我使用MySql版本5.1.56-ndb-7.1.15。请建议一种方法来做到这一点。谢谢!
答案 0 :(得分:1)
尝试以下查询:
CREATE TEMPORARY TABLE FSESSION_TEMP
(
Temp_Session_Id varchar(255)
);
INSERT INTO FSESSION_TEMP
(
SELECT a.Session_Id FROM
FSESSION a,
FSESSION b
WHERE
a.Status = 'Started' and
b.Status = 'Finished' and
a.Session_ID = b.Session_ID
LIMIT 2
);
DELETE FROM
FSESSION
WHERE
Session_ID in (SELECT * FROM FSESSION_TEMP)
;
DROP TABLE FSESSION_TEMP;
这是SQL Fiddle。我将LIMIT设置为2以表明它有效。您仍然需要将其更改为1000。
由于以下两个原因,您似乎需要使用临时表:
1)当您在子查询中使用相同的表时,MySQL不允许您从表中删除
2)对于多表语法,DELETE从每个tbl_name中删除满足条件的行。在这种情况下,不能使用ORDER BY和LIMIT(直接取自MYSQL DELETE manual)
通过DELETE
使用JOIN
语法并使用派生表(与上述临时表相同)连接原始表(将从中删除行),有一种方法可以绕过限制):
DELETE fdel
FROM
FSESSION fdel
JOIN
(
SELECT a.Session_Id
FROM
FSESSION a
JOIN
FSESSION b
ON a.Session_ID = b.Session_ID
WHERE
a.Status = 'Started' and
b.Status = 'Finished'
LIMIT 2
) ftemp
ON ftemp.Session_ID = fdel.Session_ID
;
答案 1 :(得分:1)
更新
DELETE f
FROM fsession f JOIN
(
SELECT session_id, subscriber_id
FROM fsession
WHERE status IN('Started', 'Finished')
GROUP BY Session_Id, Subscriber_Id
HAVING MAX(status = 'Started') > 0
AND MAX(status = 'Finished') > 0
LIMIT 1000 -- limit here means how many pairs of rows, so it's effectively 2x rows
) q ON f.session_id = q.session_id
AND f.subscriber_id = q.subscriber_id
要知道删除了多少行,请使用ROW_COUNT()
SELECT ROW_COUNT();
这是 SQLFiddle 演示