Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: правильно написать запрос исключив деление на ноль  (Прочитано 21624 раз)
0 Пользователей и 1 Гость смотрят эту тему.
vanillavera
Новенький

ru
Offline Offline

« : 21-07-2010 10:01 » 

Всем здравствуйте!
подскажите, пожалуйста, кто знает, как правильно написать запрос?
нужно вывести поле наценка, как результат от деления (продажи-продажи в договорных ценах)/продажи в договорных ценах
проблема в том, что договорной цены может и не быть
как написать, чтобы в случае возникновения ошибки деления на ноль в поле выводился ноль?
изначально , скажем запрос такой

SELECT access.SUMPROD, access.SUMDOG, (SUMPROD-SUMDOG)/SUMDOG
FROM access access

теоретически понимаю, что здесь нужно использовать is null или case

но как? мои познания в SQL скудны и поверхностны
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 21-07-2010 11:51 » new

Ну точно не знаю, есть или нету в Access оператор if. Если есть, то можно его применить.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #2 : 21-07-2010 11:59 » 

Сейчас подсмотрел в гугле.

SELECT access.SUMPROD, access.SUMDOG, IIf([SUMDOG]>0,(SUMPROD-SUMDOG)/SUMDOG,0)
FROM access access
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 21-07-2010 13:15 » 

Finch, а откуда речь про Access? В соседней теме разговор шёл про 1С - видимо SQL Server и в частности DBF-файлы.

Вообще по стандарту SQL-92 используется выражение CASE. Тогда:
Код: (SQL)
SELECT
  access.SUMPROD,
  access.SUMDOG,
  CASE
    WHEN access.SUMDOG = 0 THEN 0
    ELSE (access.SUMPROD - access.SUMDOG) / access.SUMDOG
  END
FROM access AS access

Хотя не уверен, что драйверы работы с DBF-файлами это поддерживают.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
HandKot
Молодой специалист

ru
Offline Offline

« Ответ #4 : 22-07-2010 04:13 » 

внесу свои пять копеек
Код:
SELECT
  access.SUMPROD,
  access.SUMDOG,
  (access.SUMPROD - access.SUMDOG) / access.SUMDOG
FROM access AS access
WHERE access.SUMDOG <> 0
UNION ALL
SELECT
  access.SUMPROD,
  access.SUMDOG,
  0
FROM access AS access
WHERE access.SUMDOG = 0


Записан

I Have Nine Lives You Have One Only
THINK!
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 22-07-2010 06:20 » 

HandKot, но минус такого решения - два отдельных запроса и, соотв., два прохода по таблице.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Kivals
Команда клуба

ca
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 22-07-2010 06:24 » 

RXL, не исключен вариант что 2 запроса (с учетом индексов) отработают быстрее, чем один с использованием CASE
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 22-07-2010 06:30 » 

Kivals, если рассматривать запросы, приведенные в данной теме, тут чистый full scan. Вариант HandKot при использовании индекса по SUMDOG не будет быстрее варианта с CASE, т.к. при операции <> индексы бесполезны: полное сканирование индекса с последующей выборкой большинства строк не быстрее полного сканирования таблицы.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
HandKot
Молодой специалист

ru
Offline Offline

« Ответ #8 : 23-07-2010 04:30 » 

RXL, Kivals надо смотреть планы выполнения и тогда точно определишь. что лучше
Записан

I Have Nine Lives You Have One Only
THINK!
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #9 : 23-07-2010 05:30 » 

"WHERE access.SUMDOG <> 0"
"WHERE access.SUMDOG = 0"

в любом случае выбираются все записи, а если с использованием индекса, то еще хуже, а бы специально пытался сделать один проход FULL SCAN
Записан

Удачного всем кодинга! -=x[PooH]x=-
HandKot
Молодой специалист

ru
Offline Offline

« Ответ #10 : 23-07-2010 13:41 » 

"WHERE access.SUMDOG <> 0"
"WHERE access.SUMDOG = 0"

в любом случае выбираются все записи, а если с использованием индекса, то еще хуже, а бы специально пытался сделать один проход FULL SCAN

при налиции более одного проца (ядра)
последний запрос будет распараллен и время выполнения должно быть меньше ИМХО
но спорить не буду
Записан

I Have Nine Lives You Have One Only
THINK!
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 23-07-2010 15:39 » 

HandKot, у нас в теме MS Access - какое уж тут распараллеливание... Улыбаюсь
Один плюс, что базы Access-а редко бывают большими.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
HandKot
Молодой специалист

ru
Offline Offline

« Ответ #12 : 26-07-2010 06:11 » 

RXL
про Acces у автора не было сказано ни слова   Улыбаюсь

по поводу планов выполнения
было проведено небольшое исследование со следующими запросами

Код:
select col1, col2, case when col1 = 0 then 0 else col2/col1 end from t
Код:
select col1, col2, isnull(col2/nullif(col1,0),0) from t
Код:
select col1, col2, col2/col1 from t where col1<> 0
union all
select col1, col2, 0 from t where col1= 0


на иаблице в 20 т. строк разница выполнения сотавила менее 5% (32, 32, 36 соответственно)


Записан

I Have Nine Lives You Have One Only
THINK!
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #13 : 26-07-2010 09:18 » 

Да, это меня Finch ввел в заблуждение... Улыбаюсь

Индексы присутствовали? Какие?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
HandKot
Молодой специалист

ru
Offline Offline

« Ответ #14 : 27-07-2010 05:05 » 

лучший рещультат дал индекс по полю col1 с INCLUDE полем col2 (MSSQL 2008)

единственное, генерил данные сам и распределение col1 по условию "не равно 0" и "равно 0" составляло 50х50
скорее всего при других условиях, результы будут разниться
Записан

I Have Nine Lives You Have One Only
THINK!
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #15 : 27-07-2010 07:06 » 

Конечно. Но в любом случае вариант запроса с UNION будет медленнее - от немного медленнее до вдвое медленнее. Остальным вариантам запросов индексы даже не требуются - там однозначный full scan.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines