“where”中的 MySql 变量子句问题
我有一个带有子查询的查询。子查询返回我需要在 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
子句中,我放置了与“criteria”列中相同的内容。如果没有 WHERE 子句,它的变量就完全按照我的预期工作。我很困惑 - 没有“哪里”:
I have a query with subquery in it. the subquery returns the value, that i need to return in php and that also is used in "where" clause. i trying to figure out how can i not exequte th subquery two times.
I trying to assign the value of it to the variable. And it works fine in "select", but when i use variable in "where" clause, the query returns 0 rows.
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()
In the WHERE
clause, I put the same as in "criteria" column. and without the WHERE clause it variable work exactly how I expect. I'm confused - without "where":
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
WHERE 子句使用执行查询之前存在的变量值。
尝试将相关子查询结果嵌入到它自己的子查询中,然后对其进行过滤。 RDBMS 足够聪明,只处理需要的内容,就好像我编写的子查询从来不存在一样...
注意:
WHERE 子句涉及为每个过期值添加 14 天。您最好从 CURDATE() 中取出 14 天,因为它只发生一次。
编辑:
另外,请注意 RDBMS 实际上非常聪明。您编写的 SQL 并不完全是执行的内容,它会被解析、优化、编译等。它最终会成为传统的顺序代码。这意味着 RDBMS 可以发现您多次编写了相同的子查询,并且知道它只需要执行一次,而不是多次...
例如,这里的两个相同的子查询不会每次执行两次记录。 RDBMS 比这更聪明:) 事实上,它甚至可以知道它只需要执行一次,因为结果不依赖于正在处理的记录。
也就是说,使用 sub_queries (例如我原来的答案)可以使代码更易于维护(只需要在一处进行更改)。
The WHERE clause is using the variable's value as present before the execution of the query.
Try embedding the correlated sub-query result in a sub-query of it's own, then filtering that. The RDBMS is clever enough to only process what is needed, as if the sub-query I've written didn't ever exist...
Note:
The WHERE clause involves adding 14 days to every expiure value. You may be better off taking 14 days from CURDATE() instead, it only happens once.
EDIT:
Also, note that RDBMS are actually quite clever. The SQL you write isn't exactly what is executed, it gets parsed, optimised, compiled, etc. It ends up as traditional sequential code. This means that the RDBMS can spot that you have the same sub-query written several times, and know that it needs only execute once, not several times...
For example, the two identical sub_queries here won't get executed twice for every record. The RDBMS is cleverer than that :) In fact, it can even tell that it only needs executing once, ever, because the result is not dependant on the records being processed.
That said, using sub_queries such as my original answer can make code easier to maintain (only need changing in one place).