2011-03-15 86 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