2009-10-20 2 views
4

У меня есть SQL, который может быть упрощен до:Как устранить дублирование вычислений в SQL?

SELECT * 
    FROM table 
WHERE LOCATE(column, :keyword) > 0 
ORDER BY LOCATE(column, :keyword) 

Вы можете видеть, что есть дубликат «LOCATE (колонок,: ключевое слово)». Есть ли способ рассчитать его только один раз?

+1

Кроме того, в случае, если вы не знали , многие базы данных позволяют создавать индекс для функции или вычисления. Поэтому, если вы обнаружите, что выполняете множество запросов на основе LOCATE (column,: keyword), вы можете создать индекс, в котором это значение было предварительно вычислено и сохранено, чтобы увеличить скорость запросов. –

+1

Вы уверены, что LOCATE вызывается дважды? – tster

+0

tster правильно - многие двигатели sql оптимизируют это. –

ответ

2

HAVING работы с псевдонимами в MySQL:

SELECT *, LOCATE(column, :keyword) AS somelabel 
FROM table 
HAVING somelabel > 0 
ORDER BY somelabel 
+0

Обратите внимание, что HAVING вычисляет весь набор результатов и затем фильтрует его. WHERE фильтрует ряд за строкой, сохраняя память. –

+0

Не только память, если условие может быть оценено из загруженных индексов, это может также экономить ввод-вывод. – Unreason

5
SELECT *, LOCATE(column, :keyword) AS somelabel 
FROM table 
WHERE somelabel > 0 
ORDER BY somelabel 
+0

Но я получил ошибку на MySQL # 1054 - Неизвестный столбца 'c1' в 'где предложение' SQL, является: SELECT *, LOCATE (имя, 'A') AS c1 FROM 'employees' WHERE c1> 0 – Cheng

+0

Этот метод не будет работать для всех баз данных. Некоторым по-прежнему потребуется явно указать функцию в предложении ordering. –

+0

Это даже работает для MySQL? http://dev.mysql.com/doc/refman/5.4/en/select.html «Нельзя ссылаться на псевдоним столбца в предложении WHERE, поскольку значение столбца может еще не определяться, когда предложение WHERE выполняется « – MartW

2

Джефф Ober имеет право идею, но здесь альтернативный метод:

SELECT 
    t.* 
,loc.LOCATED 
FROM 
    table t 
    INNER JOIN 
    (
    SELECT 
    primary_key 
    ,LOCATE(column,:keyword) AS LOCATED 
    FROM 
    table 
) loc 
    ON t.primary_key = loc.primary_key 
WHERE loc.LOCATED > 0 
ORDER BY 
    loc.LOCATED 
Смежные вопросы