2017-07-15 93 views
1

这里是我的查询:如何在UPDATE语句中使用JOIN?

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

我不认为你的括号平衡。 –

+0

@GordonLinoff真的......我又增加了一个。 –

回答

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语句中使用的表中的任何列名称相同。如果你这样做会令人困惑。

+0

谢谢.. upvote,你认为哪种方法更好?你的*(使用变量)*或戈登的答案*(使用'CROSS JOIN')*?注意到这两个工作正常。 –

+0

两者都可以正常工作,所以我会选择更直接,更易于编码的。 –

+0

你能告诉我为什么你在变量名的开头不用'@'?其实我很困惑,究竟应该在MySQL中使用'@'作为变量吗? –

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; 
+0

谢谢.. upvote,只是你认为哪种方法更好?或者你的*(使用'CROSS JOIN')*或Bill的答案*(使用变量)*?注意到这两个工作正常。 –

+1

@MartinAJ。 。 。我希望尽可能将代码保存在单个查询中。显然,比尔有很多宝贵的经验和很好的建议,他的答案反映了这一点。这两种选择都非常合理。 –