2017-07-15 129 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。 。 。我希望儘可能將代碼保存在單個查詢中。顯然,比爾有很多寶貴的經驗和很好的建議,他的答案反映了這一點。這兩種選擇都非常合理。 –