在MySQL中删除关系位置的记录?
我试图清理存储在MySQL表中的记录。如果一行包含%X%,我需要删除该行及其下一行,而不考虑内容。例如,对不起,如果桌子侮辱了任何人的智力:在MySQL中删除关系位置的记录?,mysql,relational,Mysql,Relational,我试图清理存储在MySQL表中的记录。如果一行包含%X%,我需要删除该行及其下一行,而不考虑内容。例如,对不起,如果桌子侮辱了任何人的智力: | 1 | leave alone | 2 | Contains %X% - Delete | 3 | This row should also be deleted | 4 | leave alone | 5 | Contains %X% - Delete | 6 | This row should also be deleted | 7 | leav
| 1 | leave alone
| 2 | Contains %X% - Delete
| 3 | This row should also be deleted
| 4 | leave alone
| 5 | Contains %X% - Delete
| 6 | This row should also be deleted
| 7 | leave alone
有没有一种方法可以只用几个查询就可以做到这一点?或者我必须首先使用%x%搜索参数执行SELECT查询,然后循环这些结果并执行DELETE…对于返回的每个索引+1,在单个查询中没有合理的方法来执行此操作。这是可能的,但最终不得不使用的查询将非常复杂,并且几乎肯定无法移植到其他SQL引擎
使用您在问题中描述的先选择后删除的方法。这应该是可行的,尽管它有点笨重,可能需要检查LIKE参数,因为它使用模式匹配。请参见注释 从table.db中删除 idcol在哪里 从db.table中选择idcol,其中的col类似于“%X%” 还是艾德科林
从db.table中选择idcol+1,其中col`LIKE'%X%'假设该表名为test,包含在名为id和data的列中 我们从一个SELECT开始,它为我们提供所有行的id,这些行的前一行id最高,低于当前行的id:
SELECT t1.id FROM test t1
JOIN test t2 ON
( t2.id, true )
=
( SELECT t3.id, t3.data LIKE '%X%' FROM test t3
WHERE t3.id < t1.id ORDER BY id DESC LIMIT 1 )
这给了我们3,6,2,5-很好
现在,我们不能从表中删除,也不能从MySQL中的同一个表中选择-因此,让我们使用一个临时表,将要删除的ID存储在其中,然后从该临时表中读取以从原始表中删除:
CREATE TEMPORARY TABLE deleteids (id INT);
INSERT INTO deleteids
(SELECT t1.id FROM test t1
JOIN test t2 ON
( t2.id, true )
=
( SELECT t3.id, t3.data LIKE '%X%' FROM test t3
WHERE t3.id < t1.id ORDER BY id DESC LIMIT 1 )
)
UNION
(
SELECT id FROM test WHERE data LIKE '%X%'
);
DELETE FROM test WHERE id in (SELECT * FROM deleteids);
。。。我们的测试表中只剩下ID 1、4和7
由于前面的行是使用选择的,所以您可以在一个DELETE语句中完成所有操作: 假设紧随其后的行基于基于INT的ID列的顺序,则可以使用MySQL变量来分配行号,该行号可以解释ID中的间隔:
DELETE a FROM tbl a
JOIN (
SELECT a.id, b.id AS nextid
FROM (
SELECT a.id, a.text, @rn:=@rn+1 AS rownum
FROM tbl a
CROSS JOIN (SELECT @rn:=1) rn_init
ORDER BY a.id
) a
LEFT JOIN (
SELECT a.id, @rn2:=@rn2+1 AS rownum
FROM tbl a
CROSS JOIN (SELECT @rn2:=0) rn_init
ORDER BY a.id
) b ON a.rownum = b.rownum
WHERE a.text LIKE '%X%'
) b ON a.id IN (b.id, b.nextid)
它首先获取数据并根据ID列对其进行排序,然后在几乎相同的结果集上执行偏移左连接,只是排名列落后1。这将并排获取行及其紧邻的下一行,以便我们可以在父DELETE语句中同时提取它们的两个id:
SELECT a.id, a.text, b.id AS nextid, b.text AS nexttext
FROM (
SELECT a.id, a.text, @rn:=@rn+1 AS rownum
FROM tbl a
CROSS JOIN (SELECT @rn:=1) rn_init
ORDER BY a.id
) a
LEFT JOIN (
SELECT a.id, a.text, @rn2:=@rn2+1 AS rownum
FROM tbl a
CROSS JOIN (SELECT @rn2:=0) rn_init
ORDER BY a.id
) b ON a.rownum = b.rownum
WHERE a.text LIKE '%X%'
收益率:
ID | TEXT | NEXTID | NEXTTEXT
2 | Contains %X% - Delete | 3 | This row should also be deleted
5 | Contains %X% - Delete | 6 | This row should also be deleted
257 | Contains %X% - Delete | 3434 | This row should also be deleted
4000 | Contains %X% - Delete | 4005 | Contains %X% - Delete
4005 | Contains %X% - Delete | 6000 | Contains %X% - Delete
6000 | Contains %X% - Delete | 6534 | This row should also be deleted
然后,在删除ID为子选定ID或NEXTID的行的条件下,我们加入-删除整个语句。@Aiias:这是一个完全不同的问题。这依赖于ID中的非间隙。LIKE不使用regexes,REGEXP使用;看见
ID | TEXT | NEXTID | NEXTTEXT
2 | Contains %X% - Delete | 3 | This row should also be deleted
5 | Contains %X% - Delete | 6 | This row should also be deleted
257 | Contains %X% - Delete | 3434 | This row should also be deleted
4000 | Contains %X% - Delete | 4005 | Contains %X% - Delete
4005 | Contains %X% - Delete | 6000 | Contains %X% - Delete
6000 | Contains %X% - Delete | 6534 | This row should also be deleted