2014-01-06 2 views
1

В операторе SELECT я выполняю вычисление в текущей строке и сохраняю его в столбце, в котором я указываю псевдоним. MySQL 5.5.4 не позволяет ссылаться на псевдоним столбца, как описано here.Есть ли способ сохранить переменную в инструкции SELECT?

Есть ли способ достичь идеального кода, как показано ниже? Я хотел бы избежать повторения одного и того же вычисления снова и снова. Я полагаю, что сохранение начального результата вычисления переменной (уникальной для каждой строки), и ссылка на эту переменную имела бы наибольший смысл.

код, который работает:

SELECT 
    DATEDIFF(CURDATE(), example_table.date_start) AS daysElapsed 
FROM 
    example_table 
WHERE 
    DATEDIFF(CURDATE(), example_table.date_start) > 30 
    AND 
    DATEDIFF(CURDATE(), example_table.date_start) < 60 
; 

Идеальный код: (это не работает, потому что вы не можете ссылаться на столбец Alais)

SELECT 
    DATEDIFF(CURDATE(), example_table.date_start) AS daysElapsed 
FROM 
    example_table 
WHERE 
    daysElapsed > 30 
    AND 
    daysElapsed < 60 
; 

Я упростил проблему в этом пример. Мой фактический код имеет больший расчет, который вызывается несколько раз, вероятно, делая эту оптимизацию стоящей.

+0

HAVING без GROUP BY сортируется как WHERE, но видит псевдонимы. – Mihai

+0

@Mihai Я не понимаю, что вы только что написали. Не могли бы вы расширить его? – Lemmings19

+1

Замените место, где есть. – Mihai

ответ

2

SQL, в общем, не позволяет использовать псевдонимы столбцов в предложении where. Однако он позволяет использовать псевдонимы столбцов в предложении having. Таким образом, вы можете сделать:

SELECT DATEDIFF(example_table.date_start, CURDATE()) AS daysElapsed 
FROM example_table 
HAVING daysElapsed > 30 AND daysElapsed < 60; 

В большинстве диалектов SQL, это будет либо ошибка (having, без group by) или глобальной агрегации (то есть, всегда возвращает одну строку). В MySQL having ведет себя как where, в этом случае.

Использование стандартного SQL, можно использовать подзапрос:

select daysElapsed 
from (SELECT DATEDIFF(example_table.date_start, CURDATE()) AS daysElapsed 
     FROM example_table 
    ) et 
where daysElapsed > 30 AND daysElapsed < 60; 

Вы также можете сделать это в MySQL. Но MySQL имеет тенденцию материализовать подзапросы, поэтому производительность, вероятно, будет хуже, чем для первой версии, используя having.

+0

Фантастический, используя 'HAVING' вместо' WHERE', работал отлично! Моя проблема (а не проблема примера) также содержала некоторые предложения, которые должны были быть в «WHERE», и они продолжали работать отлично после добавления «HAVING» без «GROUP BY». – Lemmings19

Смежные вопросы