Переменная MySql в задаче «где»

0

У меня есть запрос с подзапросом в нем. подзапрос возвращает значение, которое мне нужно вернуть в php, и это также используется в предложении where. я пытаюсь понять, как я могу не выполнять exquitth подзапрос два раза. Я пытаюсь присвоить значение переменной. И он отлично работает в "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 эта переменная работает точно так, как я ожидаю. Я смущен - без "where": Изображение 174551

Теги:
correlated-subquery

1 ответ

2
Лучший ответ

Предложение WHERE использует значение переменной, присутствующее перед выполнением запроса.

Попробуйте внедрить результат коррелированного подзапроса в свой собственный запрос, а затем отфильтровать его. СУРБД достаточно умна, чтобы обрабатывать только то, что нужно, как будто написанный ниже запрос никогда не существовал...

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 дней к каждому значению expiure. Возможно, вам лучше провести 14 дней с CURDATE(), это произойдет только один раз.

WHERE
  expire = CURDATE() - INTERVAL 14 DAY

EDIT:

Также обратите внимание, что СУБД на самом деле довольно умны. SQL, который вы пишете, не совсем то, что выполняется, он анализируется, оптимизируется, компилируется и т.д. Он заканчивается традиционным последовательным кодом. Это означает, что РСУБД может заметить, что у вас есть один и тот же подзапрос, написанный несколько раз, и знаю, что он должен выполняться только один раз, а не несколько раз...

Например, два идентичных суб-запроса здесь не будут выполняться дважды для каждой записи. СУРБД более умна, чем это. Фактически, она даже может сказать, что ей требуется только один раз, потому что результат не зависит от обрабатываемых записей.

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
    это круто) спасибо

Ещё вопросы

Сообщество Overcoder
Наверх
Меню