我有一个这样的表(MySQL 5.0.x,MyISAM):
response{id, title, status, ...} (status: 1 new, 3 multi)
如果至少有20个具有相同的标题,我想将所有回复的状态从新(status=1
)更新为多个(status=3
)。
我有这个,但它不起作用:
UPDATE response SET status = 3 WHERE status = 1 AND title IN (
SELECT title FROM (
SELECT DISTINCT(r.title) FROM response r WHERE EXISTS (
SELECT 1 FROM response spam WHERE spam.title = r.title LIMIT 20, 1)
)
as u)
请注意:
You can't specify target table 'response' for update in FROM clause
GROUP BY
。使用LIMIT
的解决方案的查询成本更好(但不太可读)。编辑:
我找到的唯一解决方案是使用GROUP BY
:
UPDATE response SET status = 3
WHERE status = 1 AND title IN (SELECT title
FROM (SELECT title
FROM response
GROUP BY title
HAVING COUNT(1) >= 20)
as derived_response)
感谢您的帮助! :)
答案 0 :(得分:1)
当您尝试在一个查询中从同一个表中进行UPDATE和SELECT时,MySQL不喜欢它。它与锁定优先级等有关。
以下是我将如何解决这个问题:
SELECT CONCAT('UPDATE response SET status = 3 ',
'WHERE status = 1 AND title = ', QUOTE(title), ';') AS sql
FROM response
GROUP BY title
HAVING COUNT(*) >= 20;
此查询生成一系列UPDATE语句,引用的标题值得嵌入更新。捕获结果并将其作为SQL脚本运行。
我知道MySQL中的GROUP BY
经常会产生一个临时表,这可能会很昂贵。但这是一个交易破坏者吗?您需要多久运行一次此查询?此外,任何其他解决方案也可能需要临时表。
我可以想到一种不使用GROUP BY
来解决这个问题的方法:
CREATE TEMPORARY TABLE titlecount (c INTEGER, title VARCHAR(100) PRIMARY KEY);
INSERT INTO titlecount (c, title)
SELECT 1, title FROM response
ON DUPLICATE KEY UPDATE c = c+1;
UPDATE response JOIN titlecount USING (title)
SET response.status = 3
WHERE response.status = 1 AND titlecount.c >= 20;
但是这也使用临时表,这就是为什么你试图避免首先使用GROUP BY
。
答案 1 :(得分:0)
这是一个有趣的MySQL特性 - 我想不出在单个语句中做到这一点的方法(GROUP BY或没有GROUP BY)。
您可以先在临时表中选择相应的响应行,然后从该临时表中进行选择来进行更新。
答案 2 :(得分:0)
你必须使用临时表:
create temporary table r_update (title varchar(10));
insert r_update
select title
from response
group
by title
having count(*) < 20;
update response r
left outer
join r_update ru
on ru.title = r.title
set status = case when ru.title is null then 3 else 1;
答案 3 :(得分:0)
我会像下面那样直截了当地写一些
UPDATE `response`, (
SELECT title, count(title) as count from `response`
WHERE status = 1
GROUP BY title
) AS tmp
SET response.status = 3
WHERE status = 1 AND response.title = tmp.title AND count >= 20;
使用GROUP BY真的那么慢吗?您尝试实现的解决方案看起来像在同一个表上一次又一次地请求,并且如果它工作的话应该比使用GROUP BY慢。