2012-09-21 94 views
2

我有以下SQL代碼;重新使用父語句中的嵌套SQL語句在MySQL

SELECT a.*, b.maxDate as last_payment_date, c.package as payment_for_package, (SELECT COUNT(id) FROM uploads WHERE user = a.id) AS upload_count 
       FROM users a 
        INNER JOIN payments c 
         ON a.id = c.user_id 
        INNER JOIN 
        (
         SELECT user_id, MAX(date) maxDate, period 
         FROM payments 
         GROUP BY user_id 
        ) b ON c.user_id = b.user_id AND 
          c.date = b.maxDate 

       WHERE a.package = 1 
       AND b.maxDate < $twomonths 
       AND (SELECT COUNT(id) FROM uploads WHERE user = a.id) > 10 
       AND b.period = 1 
       ORDER BY b.maxDate ASC 
       LIMIT 50 

正如你可以看到我使用嵌套的語句(SELECT COUNT(id) FROM uploads WHERE user = a.id)兩次,我想知道如果有一種方法可以重新使用該語句,以提高性能?我已經使用別名upload_count嘗試,但你不能在WHERE條款使用別名。感謝幫助

+0

也許你應該備份,並詢問如何寫一個好的查詢來獲取數據了(張貼的模式和一些相同的數據)。很難相信,這個查詢是可以做的最好的,不管你是否可以重複使用它的一部分。 –

回答

3

剛剛加入到子查詢和結果進行相關性:

SELECT 
    a.*, 
    b.maxDate as last_payment_date, 
    c.package as payment_for_package, 
    upload_counts.upload_count 

FROM users a 

INNER JOIN payments c 
    ON a.id = c.user_id 

INNER JOIN 
(
    SELECT user_id, MAX(date) maxDate, period 
    FROM payments 
    GROUP BY user_id 
) b ON c.user_id = b.user_id AND 
     c.date = b.maxDate 

INNER JOIN 
(
    SELECT user, COUNT(id) AS upload_count 
    FROM uploads 
    GROUP BY user 
) upload_counts ON upload_counts.user = a.id 

WHERE a.package = 1 
AND b.maxDate < $twomonths 
AND upload_counts.upload_count > 10 
AND b.period = 1 

ORDER BY b.maxDate ASC 
LIMIT 50; 
+0

是的,現在更快。謝謝你 – Wasim

+0

沒問題。需要注意的是速度的提高是不可能的,因爲子查詢是在原來的查詢被執行了兩次,但因爲它被執行兩次*每個結果行*。該版本在整個查詢中爲'uploads'表執行一次查詢。 – cdhowie