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);

Это решение помогает в большинстве случаев скомпилировать запрос, но я пока не знаю, как это влияет на производительность.