这是我的问题:
UPDATE reputations SET
type = new.type,
score = new.score,
qora = NOT (new.post_id = (SELECT t1.id
FROM qanda t1
WHERE (EXISTS (SELECT 1
FROM qanda t2
WHERE ID = new.post_id
AND t1.ID = t2.related)
OR t1.id = new.post_id)
AND Type = 0)),
question_id = (SELECT t1.id
FROM qanda t1
WHERE (EXISTS (SELECT 1
FROM qanda t2
WHERE ID = new.post_id
AND t1.ID = t2.related)
OR t1.id = new.post_id)
AND Type = 0),
post_id = new.post_id,
table_code = new.table_code,
comment_id = new.comment_id,
owner_id = new.author_id,
date_time = UNIX_TIMESTAMP()
WHERE events_table_id = old.id;
我要做的就是删除其中一个子查询,因为两者都是相同的。我怎么能这样做?
答案 0 :(得分:2)
在这种情况下,我会DECLARE
一个局部变量来存储子查询的结果。阅读https://dev.mysql.com/doc/refman/5.7/en/stored-program-variables.html
使用SELECT...INTO
语法将查询结果存储到变量中。阅读https://dev.mysql.com/doc/refman/5.7/en/select-into.html
BEGIN
DECLARE QANDA_ID INT;
SELECT t1.id FROM qanda t1
WHERE (EXISTS (SELECT 1 FROM qanda t2 WHERE ID = new.post_id AND t1.ID = t2.related)
OR t1.id = new.post_id) AND Type = 0
INTO QANDA_ID;
UPDATE reputations SET ...
qora = not (new.post_id = QANDA_ID),
question_id = QANDA_ID,
...
END
我在所有大写字母中创建了变量名,只是为了让它在这个例子中脱颖而出。但是你可以将它命名为任何你想要的名称,它遵循与其他标识符名称相同的规则。
但是,我建议您不要将本地变量命名为与您在UPDATE语句中使用的表中的任何列名相同。如果你这样做会让人感到困惑。
答案 1 :(得分:1)
在我看来,您可以使用CROSS JOIN
:
UPDATE reputations r CROSS JOIN
(SELECT t1.id
FROM qanda t1
WHERE (EXISTS (SELECT 1
FROM qanda t2
WHERE ID = new.post_id and t1.ID = t2.related
) OR
t1.id = new.post_id
) AND
Type = 0
) t1
SET r.type = new.type,
r.score = new.score,
r.qora = not (new.post_id = t1.id),
r.question_id = t1.id,
r.post_id = new.post_id,
r.table_code = new.table_code,
r.comment_id = new.comment_id,
r.owner_id = new.author_id,
r.date_time = UNIX_TIMESTAMP()
WHERE r.events_table_id = old.id;