оптимизировать SQL-запрос, не повторяя математику - PullRequest
1 голос
/ 05 мая 2010

Вот запрос в Oracle, из которого я пытался удалить избыточную математическую операцию:

ВЫБРАТЬ имя,

     CASE 
       when nvl(num1,0) + nvl(num2,0) - nvl(num3,0) > 0
       THEN nvl(num1,0) + nvl(num2,0) - nvl(num3,0)
       ELSE 0
      END
      as result,
      .... from ....

Как не повторить суммирование выше?

'Результат' должен содержать - значение вышеприведенного выражения, если> 0

                    -  0 if the value of expression is <= 0.

Ответы [ 3 ]

4 голосов
/ 06 мая 2010

В этом случае вы можете заменить выражение CASE на:

GREATEST( nvl(num1,0) + nvl(num2,0) - nvl(num3,0), 0 )

Ответ OrbMan более полезен.

3 голосов
/ 05 мая 2010

Если вы хотите избавиться от математики по соображениям производительности, лучший способ сделать это (с точки зрения администратора базы данных) - создать еще один столбец с именем result, а затем использовать триггер вставки / обновления для автоматического заполнения. это когда строка изменяется, со значением, которое вы хотите:

CASE 
   WHEN nvl(num1,0) + nvl(num2,0) - nvl(num3,0) > 0
   THEN nvl(num1,0) + nvl(num2,0) - nvl(num3,0)
   ELSE 0
END

Таким образом, вычисление выполняется только при необходимости (при создании / изменении строки), а не при при каждом чтении . Это амортизирует стоимость операций с базами данных, которые читаются чаще, чем записаны (что, по моему опыту, близко ко всем из них).

Тогда ваш запрос станет простым и ослепительно быстрым:

select name, result from ...

Этот метод работает, потому что:

  • Подавляющее большинство баз данных действительно читаются гораздо чаще, чем пишутся; и
  • дисковое пространство дешевле, чем нагрузка на процессор (сравните количество вопросов о производительности базы данных с требованиями к хранилищу - первые значительно перевешивают последние).
  • запросы к базе данных с функциями для каждой строки редко масштабируются, так как таблицы становятся больше.

Все это предполагает, что Oracle имеет триггеров, конечно. Я сам человек DB2, но я был бы удивлен, если бы Oracle был настолько мертв, что у него их не было. Опять же, насколько я знаю, возможно, Oracle все еще не может различить NULL и пустую строку, так кто знает? : -)

3 голосов
/ 05 мая 2010

Использовать производную таблицу:

select name, nvl(CASE when sumall > 0 THEN sumall end, 0) as result
from (
    select nvl(num1,0) + nvl(num2,0) - nvl(num3,0) sumall, name
    from MyTable
) a
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...