MySQL: используйте значение из select в самом select
Во-первых, если у кого-то есть лучший титул, пожалуйста, помогите.
Если я скажу таблицу "календарь" со столбцом "день". И у меня есть следующий запрос:
SELECT day, day AS testDay, testDay AS test2Day FROM calendar
MySQL будет жаловаться, что "testDay" - неизвестный столбец. Конечно, вы скажете мне, что это утверждение бесполезно, но мое утверждение больше похоже на следующее:
SELECT day, SOME_CRAZY_EXPRESSION_OF(day) AS testDay, EXPRESSION_OF(testDay) AS test2Day FROM calendar
И дело в том, что я не хочу дважды оценивать первое выражение, чтобы использовать его во втором выражении. Так есть способ использовать значение, вычисленное в select как часть самого выбора?
Конечно, я мог бы сделать:
SELECT day, SOME_CRAZY_EXPRESSION_OF(day) AS testDay, EXPRESSION_OF(SOME_CRAZY_EXPRESSION_OF(day)) AS test2Day FROM calendar
Но я стараюсь избегать траты. Если у меня нет выбора, что я сделаю.
Ответы
Ответ 1
В MySQL вам нужно присвоить временную переменную значение выражения, которое сможет его повторно использовать, это должно сделать это:
SELECT day, @tmp:=SOME_CRAZY_EXPRESSION_OF(day) AS testDay,
EXPRESSION_OF(@tmp) AS test2Day FROM calendar
См. эту страницу для другого примера с большим анализом влияния производительности.
Ответ 2
Итак, вы не можете использовать переменные, потому что они содержат значение из предыдущей строки (из официальных документов: https://dev.mysql.com/doc/refman/5.0/en/user-variables.html):
SELECT (@aa:=id) AS a, (@aa+3) AS b FROM tbl_name HAVING b=5;
Ссылка на b в предложении HAVING означает псевдоним для выражение в списке выбора, который использует @aa. Это не работает Ожидается: @aa содержит значение id из предыдущей выбранной строки, не из текущей строки.
И вот почему я основал временное решение, основанное на фрагментах кода.
Я покажу пример в PHP:
$querySubstitutions = array(
'%days%' => 'TO_DAYS(table.started_at + INTERVAL (table.period - 1) DAY)'
);
$query = 'SELECT %days% AS days, <EXPRESSION_OF( %days% )> FROM table';
// Replacing pairs in a query
$query = strtr($query, $querySubstitutions);
Это решение помогает в большинстве случаев скомпилировать запрос, но я пока не знаю, как это влияет на производительность.