2011-03-15 77 views
0

我有一個查詢,其中有子查詢。子查詢返回的值,我需要返回在PHP中,也被用於「where」子句。我想弄清楚如何不能執行子查詢兩次。 我試圖將它的值賦給變量。它在「select」中工作正常,但是當我在「where」子句中使用變量時,查詢返回0行。MySql變量中「where」子句問題

SELECT t.tour_id, t.tour_name, u.company_name, u.first_name, u.last_name, 
     @expireDate:= (SELECT DATE_ADD(tour_start_date, INTERVAL (t.tour_duration - 1) DAY) 
         FROM travelhub_tours_instance 
         WHERE tour_id = t.tour_id 
        ORDER BY tour_start_date DESC 
         LIMIT 1) AS expire, 
     (@expireDate + INTERVAL 14 DAY) AS expirediff, 
     CURDATE() AS now, 
     ((@expireDate + INTERVAL 14 DAY) = CURDATE()) AS criteria 
    FROM travelhub_tours t 
    JOIN travelhub_users u ON t.operator_id = u.user_id 
WHERE (@expireDate + INTERVAL 14 DAY) = CURDATE() 

WHERE子句中,我把它和「criteria」列中的相同。如果沒有WHERE子句,它的變量就像我期望的那樣工作。我很困惑 - 沒有「where」: enter image description here

回答

2

WHERE子句在執行查詢之前使用變量的值。

嘗試將相關的子查詢結果嵌入到它自己的子查詢中,然後過濾該結果。該RDBMS是很聰明,只是需要什麼,彷彿子查詢,我寫不存在過......過程

SELECT 
    tour_id, tour_name, company_name, first_name, last_name, expire, 
    (expire + INTERVAL 14 DAY) AS expirediff, 
    CURDATE() AS now, 
    ((expire + INTERVAL 14 DAY) = CURDATE()) AS criteria 
FROM 
(
    SELECT 
    t.tour_id, t.tour_name, u.company_name, u.first_name, u.last_name, 
    (SELECT DATE_ADD(tour_start_date, INTERVAL (t.tour_duration - 1) DAY) 
     FROM travelhub_tours_instance 
     WHERE tour_id = t.tour_id 
    ORDER BY tour_start_date DESC 
    LIMIT 1) AS expire 
    FROM 
    travelhub_tours t 
    JOIN 
    travelhub_users u 
     ON t.operator_id = u.user_id 
) 
    AS sub_query 
WHERE 
    (expire + INTERVAL 14 DAY) = CURDATE() 

注:

WHERE子句涉及添加14天到每個到期價值。您最好從CURDATE()中抽取14天,而不是隻發生一次。

WHERE 
    expire = CURDATE() - INTERVAL 14 DAY 

編輯:

另外,還要注意RDBMS實際上是相當聰明的。你編寫的SQL並不完全是執行的,它被解析,優化,編譯等。它最終成爲傳統的順序代碼。這意味着RDBMS可以發現你有多次寫入的相同的子查詢,並且知道它只需要執行一次,而不是幾次...

例如,這裏的兩個相同的子查詢不會得到每條記錄執行兩次。 RDBMS比這更聰明:)事實上,它甚至可以告訴它只需要執行一次,因爲結果不依賴於正在處理的記錄。

SELECT 
    (SELECT MAX(event_date) FROM event_table) AS max_event_date, 
    event_date 
FROM 
    event_table 
WHERE 
    (SELECT MAX(event_date) FROM event_table) - INTERVAL 7 DAY <= event_date 

也就是說,使用sub_queries如我原來的答覆可以使代碼更易於維護(只需要在一個地方改變)。

+0

很酷)謝謝 – 2011-03-15 16:35:12