简体   繁体   English

MySql变量在“where”子句中出现问题

[英]MySql variable in “where” clause problem

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. 子查询返回值,我需要在php中返回,并且还在“where”子句中使用。 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”中工作正常,但是当我在“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()

In the WHERE clause, I put the same as in "criteria" column. WHERE子句中,我将其与“条件”列中的相同。 and without the WHERE clause it variable work exactly how I expect. 并且没有WHERE子句,它变量的工作方式与我的预期完全一致。 I'm confused - without "where": 我很困惑 - 没有“在哪里”: 在此输入图像描述

The WHERE clause is using the variable's value as present before the execution of the query. WHERE子句在执行查询之前使用变量的值。

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... 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()

Note: 注意:

The WHERE clause involves adding 14 days to every expiure value. WHERE子句涉及为每个expeure值添加14天。 You may be better off taking 14 days from CURDATE() instead, it only happens once. 你可能最好从CURDATE()开始服用14天,它只会发生一次。

WHERE
  expire = CURDATE() - INTERVAL 14 DAY

EDIT: 编辑:

Also, note that RDBMS are actually quite clever. 另外,请注意RDBMS实际上非常聪明。 The SQL you write isn't exactly what is executed, it gets parsed, optimised, compiled, etc. It ends up as traditional sequential code. 您编写的SQL并不完全是执行的,它会被解析,优化,编译等。它最终成为传统的顺序代码。 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... 这意味着RDBMS可以发现您有多次写入相同的子查询,并且知道它只需执行一次,而不是几次......

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. 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

That said, using sub_queries such as my original answer can make code easier to maintain (only need changing in one place). 也就是说,使用我的原始答案之类的子查询可以使代码更容易维护(只需要在一个地方进行更改)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM