我有一个子查询的查询。子查询返回值,我需要在php中返回,并且还在“where”子句中使用。我想弄清楚我怎么能不两次执行子查询。 我试图将它的值赋给变量。它在“select”中工作正常,但是当我在“where”子句中使用变量时,查询返回0行。
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
子句中,我将其与“条件”列中的相同。并且没有WHERE子句,它变量的工作方式与我的预期完全一致。我很困惑 - 没有“在哪里”:
答案 0 :(得分: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子句涉及为每个expiure值添加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
也就是说,使用我的原始答案之类的子查询可以使代码更容易维护(只需要在一个地方进行更改)。