2013-08-08 3 views
2

Скажем, у меня есть кое-что, как основной, какMySQL возвращаемый результат запроса, если условие выполняется, без повторения запроса

SELECT IF((1 + 2) >=0, (1 + 2), 0) 
FROM DUAL 

, который, очевидно, будет возвращать 3.

Есть ли способ, чтобы не повторять ввода запроса хотите вернуться (здесь 1 + 2)?

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

то, что я сделал это

IF((4 - IFNULL((LONG QUERY RETURNING THE NUMBER OF TASKS DONE THIS MONTH FOR A PARTICULAR USER),0)) >= 0, 
(4 - IFNULL((LONG QUERY RETURNING THE NUMBER OF TASKS DONE THIS MONTH FOR A PARTICULAR USER), 
0) 

Но есть способ, чтобы не повторить запрос, так как это долго, и я не хочу, сервер должен выполнить тот же запрос дважды ?

ответ

4

В зависимости ваш запрос, вы можете захотеть использовать user-defined variables:

SELECT 1+2 INTO @tmp; 
SELECT IF(@tmp >=0, @tmp, 0) 

Или, если вы хотите один лайнеры

SELECT IF((@tmp := (1+2)) >=0, @tmp, 0) 
--  ^   ^
--  don't forget those parenthesis ! 

EDIT: Это работает для «таблицы выбора »также:

CREATE TABLE tbl AS SELECT 1 as a UNION SELECT 2; 
SELECT SUM(a) FROM tbl INTO @tmp; 
SELECT IF (@tmp > 0, @tmp, 0); 

Если посмотреть на http://sqlfiddle.com/#!2/37c33/1 для плана выполнения указанных выше запросов, вы увидите второй SELECT не использовать таблицу.


BTW, пожалуйста, обратите внимание, что с фактическим, например, это могло быть написано:

SELECT MAX((1+2), 0) 
--   ^^^^^ here your expression 

... но я думаю, что это не свойство вашего реального запроса?

+0

Дело в том, что это часть большего запроса. Это один из _select_expr_ оператора SELECT. Я не думаю, что это было бы возможно ... –

+0

@JPP. Вероятно, вам нужно будет показать пример * актуального * запроса. Но, насколько я могу судить, [согласно документу] (http://dev.mysql.com/doc/refman/5.0/en/select.html), * select_expr * разрешен в 'SELECT ... INTO ' –

+0

-Необновляя первый комментарий, я не видел вашего редактирования во время написания - я не думал о том, чтобы делать' MAX() ', но теперь, когда вы это сказали, это действительно сработает. Но метод, который я должен использовать, - это тот, который вы предложили. Я не знал, что могу это сделать, спасибо! –

2

Вы можете сделать это:

SELECT IF((@a:=(1 + 2)) >=0, @a, 0); 
1

Одно утверждение решения

способ решить эту проблему в MySQL, чтобы сохранить результат тяжелого запроса и повторно использовать несколько раз. Посмотрите здесь:

SELECT CASE 
    WHEN @Value - 4 > 0 
    THEN @Value ELSE 0 
    END 
FROM (SELECT @Value := (SELECT 1)) Query 

где «SELECT 1» следует заменить вашим запросом.

OT

Другой способ выполнить запрос потребует поддержки КТР (Common Таблица Expression).

За то, что я знаю, что эта функция отсутствует в MySQL (How to transform a MSSQL CTE query to MySQL?)

Просто чтобы дать вам вкус его выразительности в MSSQL, где КТР доступен, вы могли бы написать что-то вроде этого:

with Query (value) 
as 
(
    select 1 
) 
select 
    case 
    when (select value from Query) - 4 > 0 
     then (select value from Query) 
    else 
     0 
    end 

Действительно, CTE более мощные, особенно при работе с рекурсивными отношениями.

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