Имя: Пароль:
1C
1С v8
Вопрос по ЕСТЬNULL в запросе.
0 Повелитель
 
13.02.13
13:12
1. 1 Вариант 100% (3)
2. 2 Вариант 0% (0)
Всего мнений: 3

Вот задумался есть ли разница в запросе:
|    ЕСТЬNULL(СУММА(Продажи.КоличествоОборот),0) КАК ПродажиКоличество
или так:
|    СУММА(ЕСТЬNULL(Продажи.КоличествоОборот,0)) КАК ПродажиКоличество
1 Classic
 
13.02.13
13:13
Есть
2 Волшебник
 
13.02.13
13:13
лучше второй вариант
3 Восточный Парень
 
13.02.13
13:14
(2) +1
4 Maxus43
 
13.02.13
13:14
2-й по феншую
5 smitru
 
13.02.13
13:14
Есть

Если в Продажи.КоличествоОборот будет NULL, то первое выдаст фигню, а второе будет работать корректно :-)
6 Повелитель
 
13.02.13
13:14
Спасибо.
7 Classic
 
13.02.13
13:14
На наборе
1
2
NULL
3

Первый выдаст 6, второй 0
8 Classic
 
13.02.13
13:14
(7)Наоборот
9 Повелитель
 
13.02.13
13:15
Спасибо, все понятно.
10 Как страшно жить
 
13.02.13
13:15
(0) первый всегда выдаст число, второй может выдать NULL
(7) оба выдадут 6
11 Как страшно жить
 
13.02.13
13:16
(5) ложь это и провокация
12 Как страшно жить
 
13.02.13
13:16
(9) тебе врут, а ты веришь
13 Humandra
 
13.02.13
13:17
вот уже вторую тему с таким мнением читаю - что второй вариант лучше.

а по моему на агрегатных функциях суммирование как в 7 всегда выдаст нормальное количество

а вот если будет вариант
sum(null), то результат будет null

и первый вариант выдал бы число
14 Humandra
 
13.02.13
13:17
т.е. мое мнение - первый корректен, второй - ошибочен
15 Maxus43
 
13.02.13
13:18
работа их будет с точки зрения юзера - одинаковая, с точки зрения системы лучше 2-й вариант
16 Как страшно жить
 
13.02.13
13:18
(13) единственный вариант расхождения в результатах, это вариант пустой выборки
17 Humandra
 
13.02.13
13:18
(16) да, я и имею его в виду
18 Maxus43
 
13.02.13
13:18
>>а вот если будет вариант
sum(null), то результат будет null

второй вариант исключает эту ситуацию, а первый наоборот позволяет
19 Как страшно жить
 
13.02.13
13:18
(15) разница есть, но редко встречается
20 Defender aka LINN
 
13.02.13
13:19
(13) А второй, типа, дату вернет, да?
21 Humandra
 
13.02.13
13:19
(16) т.е. когда к, примеру, продаж не было вообще
первый вариант даст 0
второй - null (а как правило, это не то, что нужно)
22 Как страшно жить
 
13.02.13
13:19
(2) там не всегда число может получиться, а в 1-м варианте всегда
23 Maxus43
 
13.02.13
13:19
(21) наоборот. второй даст 0
24 Как страшно жить
 
13.02.13
13:19
(20) нет, NULL
25 Humandra
 
13.02.13
13:20
(20) второй выдаст null
и при попытке оперирования этим null мы получим ошибку преобразования типов
26 Как страшно жить
 
13.02.13
13:20
(23) брешишь
27 Как страшно жить
 
13.02.13
13:20
давайте голосовалку
28 Повелитель
 
13.02.13
13:20
Не думал я, что такой вопрос может мнения раздвоиться.
29 Maxus43
 
13.02.13
13:21
вы про пустую выборку щас? если она не пустая - 2й вариант даст число всегда. Приведите пример обратного
30 Повелитель
 
13.02.13
13:21
(27) Как это сделать?
32 Shurjk
 
13.02.13
13:22
(28) Ну дык лучше часами спорить чем просто проверить.
33 Humandra
 
13.02.13
13:22
(29) если выборка непустая, то вариант 1 и 2 эквавалентны полностью
зато если она пустая, то вариант 2 даст ошибку
34 smitru
 
13.02.13
13:22
(30) Критерий истины - практика

Запускаешь 1С, делаешь ТабличнуюЧасть и смотришь сам в запросе...
35 Как страшно жить
 
13.02.13
13:23
проверяю:

ВЫБРАТЬ
   ЕСТЬNULL(СУММА(1), 0) КАК Поле1,
   СУММА(ЕСТЬNULL(1, 0)) КАК Поле2
ИЗ
   Справочник.Номенклатура КАК Номенклатура
ГДЕ
   ЛОЖЬ

на непустых выборках результат ВСЕГДА равен
36 smitru
 
13.02.13
13:24
Млин... курите сударь "агрегатные функции" SQL и что выдают они если среди элементов суммирования встречается именно NULL

Для этого и ввели ЕСТЬNULL()
37 Как страшно жить
 
13.02.13
13:24
(36) она ихигнорирует просто, не знал?
38 Shurjk
 
13.02.13
13:25
(36) И что они выдадут?
39 smitru
 
13.02.13
13:25
(35) ё-ё-ё-ё.. ну всё понятно.. про группировки ещё видно не дочитал... Где в твоём запросе группировка??? :-)
40 Повелитель
 
13.02.13
13:25
Все я проверять полез. На форум и зашел чтобы без тестирования это узнать.
41 Maxus43
 
13.02.13
13:26
(40) правильно, миста лучший отладчик
42 smitru
 
13.02.13
13:27
(40) зря... тут быдлокодеров тьма тьмущая :-)
43 Как страшно жить
 
13.02.13
13:27
(39) она не обязательна вообще то
44 Как страшно жить
 
13.02.13
13:30
вообще 1С-ники переняли довольно неудачный вариант, по фэн-шую правильно COALESCE
45 acsent
 
13.02.13
13:32
разница будет на наборах без данных. Первый выдаст 0, второй NULL
46 Повелитель
 
13.02.13
13:32
Вот запрос накидал:

ВЫБРАТЬ
   спрНом.Ссылка,
   СУММА(ТоварыНаСкладахОстатки.КоличествоОстаток)+1 КАК КоличествоОстаток,
   ЕСТЬNULL(СУММА(ТоварыНаСкладахОстатки.КоличествоОстаток), 0)+1 КАК КоличествоОстаток1,
   СУММА(ЕСТЬNULL(ТоварыНаСкладахОстатки.КоличествоОстаток, 0))+1 КАК КоличествоОстаток2
ИЗ
   Справочник.Номенклатура КАК спрНом
       ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
       ПО спрНом.Ссылка = ТоварыНаСкладахОстатки.Номенклатура
ГДЕ
   спрНом.Ссылка В ИЕРАРХИИ(&Ссылка)

СГРУППИРОВАТЬ ПО
   спрНом.Ссылка
ИТОГИ
   СУММА(КоличествоОстаток),
   СУММА(КоличествоОстаток1),
   СУММА(КоличествоОстаток2)
ПО
   ОБЩИЕ

Сумма итогов:
КоличествоОстаток 2 943,
КоличествоОстаток1 3 123,
КоличествоОстаток2 3 123

Разницы по 1 и второму варианту не вижу, без ЕСТЬNULL отрабатывает некорректно.
47 smitru
 
13.02.13
13:33
Читаем букварь

Агрегатная функция СУММА

Функция вычисляет арифметическую сумму всех попавших в выборку значений поля.

В качестве параметра функции можно указывать только поля, содержащие числовое значение.

Если поле не может содержать числовых значений, то применение функции СУММА к такому полю вызовет ошибку. Если поле может содержать числовые значения (имеет составной тип данных), то данная функция может быть применена к такому полю. Но если среди значений поля в выборке встретится нечисловое значение (помимо значений NULL), это вызовет ошибку.

Много раз перечитываем последнее предложение и думаем, думаем, думаем
48 Как страшно жить
 
13.02.13
13:34
(47) я уже давно правильный ответ тут написал и не раз
49 acsent
 
13.02.13
13:34
(46) Тебе 5 раз сказали где разница
50 Повелитель
 
13.02.13
13:34
(47) У меня только числовое и NULL, поэтому ошибки не вылетает.
51 Humandra
 
13.02.13
13:36
(47) здесь не написано, что если среди данных встретиться null, то агрегатная функция вернет ошибку или null

практика, что характерно, подтверждает мое мнение :)
52 Повелитель
 
13.02.13
13:36
(48) (49) Это хорошо что у вас мнение по этому поводу железное. А как быть мне, если мнения на форуме разошлись?
Спрошу по другому. У меня запрос будет типа (46), какой вариант там выбрать лучше.
53 Как страшно жить
 
13.02.13
13:37
(52) в твоем случае без разницы
54 Повелитель
 
13.02.13
13:38
(53) Спасибо :)
55 smitru
 
13.02.13
13:39
(47) 1 + 2 + 3 + 4 = 10
    1 + 2 + null + 4 = null
    ЕСТЬNULL(1, 0) + ЕСТЬNULL(2,0) + ЕСТЬNULL(null,0) + ЕСТЬNULL(4, 0) = 7

Не видишь разницы?
56 Как страшно жить
 
13.02.13
13:40
(55) а теперь с агрегатными функциями ))
57 Повелитель
 
13.02.13
13:42
(55) В моем случае будет так я понял:

ЕСТЬNULL(1, 0) + ЕСТЬNULL(2,0) + ЕСТЬNULL(null,0) + ЕСТЬNULL(4, 0) = 7
ЕСТЬNULL(1 + 2 + null + 4),0) = 7
58 GANR
 
13.02.13
13:43
Только так: СУММА(ЕСТЬNULL(Продажи.КоличествоОборот,0)).
59 Humandra
 
13.02.13
13:45
(57) да. но не 1 + 2 + null + 4
а
СУММА(1, 2, null, 4)

налл + число будет налл
но для агрегатных функций это неверно, они суммируют, игнорируя наллы
60 Повелитель
 
13.02.13
13:45
(59) Понял
61 Humandra
 
13.02.13
13:46
(58)
тогда попробуй на таком запросе
выбрать СУММА(ЕСТЬNULL(Продажи.КоличествоОборот,0))
 из таблицы
 где 1 <> 1
62 acsent
 
13.02.13
13:46
(52) в твоем случае сумма вообще не нужна, как и сгруппировать
63 Повелитель
 
13.02.13
13:47
(62) Это упрощенный запрос, у меня данные берутся из вложенного запроса, но суть та же.
64 DexterMorgan
 
13.02.13
13:48
(55) по-видимому тебе нужно перечитать (47) до просветления.
65 Darklight
 
13.02.13
13:48
В приведённом в (0) сабже первый вариант более корректен. Так как агрегат СУММА() при обработке NULL считает его как 0 и нормально суммирует. А вот, если исходный набор будет пустым - агрегат вернёт NULL (в одной единственной строке) - а если написать ЕСТЬNULL(Сумма(Продажи.КоличествоОборот),0) - то в этой строке будет 0.
66 Humandra
 
13.02.13
13:52
(65) почему-то уже во второй теме эта простая вещь очень долго до народа доходит :)

кстати, ИМХО, первый вариант чуть лучше еще и тем, что ЕСТЬNULL будет вызываться только один раз после суммирования. Правда, это экономия на спичках, но все же душу греет :)
67 Humandra
 
13.02.13
13:55
проголосовала :)

1 Вариант
68 Повелитель
 
13.02.13
13:55
Пусть голосовалка будет :)
Я бы сразу поверил  Как страшно жить, если бы в этой теме не отписался Волшебник, а я на его учебнике учился можно сказать!
69 Как страшно жить
 
13.02.13
13:56
Кстати да

1 Вариант
70 Darklight
 
13.02.13
13:57
появилась голосовалака  значит

1 Вариант
71 Darklight
 
13.02.13
14:00
Обычно в голосовалках бывает не менее 3-х вариантов и обычно бывает вариант "Прочее" - где тут такое?
Вот, можно было бы и такой вариант предложить
ЕСТЬNULL(СУММА(ЕСТЬNULL(Продажи.КоличествоОборот,0)),0) КАК ПродажиКоличество
Это уж точно наверняка ;)
72 Повелитель
 
13.02.13
14:01
(71) Уже не могу поменять.
73 Darklight
 
13.02.13
14:01
(66)Волшебник за второй вариант - он знает в этом толк ;)
74 Humandra
 
13.02.13
14:03
но вот такое:
ЕСТЬNULL(СУММА(Продажи.Количество1 + Продажи.Количество2),0)

работать будет некорректно
думаю, почему - очевидно
75 Darklight
 
13.02.13
14:11
(74)В общем случае - да - может работать некорректно
А давайте новую тему и новый опрос откроем
Что лучше

СУММА(ЕСТЬNULL(Продажи.Количество1,0) + ЕСТЬNULL(Продажи.Количество2,0))

или

ЕСТЬNULL(СУММА(Продажи.Количество1) + СУММА(Продажи.Количество2),0)

Кстати, почему-то никто не поднял вопрос, кто такие эти "Продажи" и откуда там вообще могут взяться значения NULL
Например, все таблицы регистра накопления не порождают сами по себе значения NULL - они могут возникнуть только в левых/правых/полных соединениях, с использованием данной таблицы.
В этом случае в(72) поля Количество1 и Количество2 могут быть NULL только одновременно (и это отработает корректно), но если там "Продажи" - это произвольная таблица, скажем из под-запроса - то эти поля в общем случае могут иметь произвольные значения.
76 Humandra
 
13.02.13
14:17
(75) тот же принцип, что и в (0)
лучше
ЕСТЬNULL(СУММА(Продажи.Количество1) + СУММА(Продажи.Количество2),0)

потому что агрегатная функция налл в результате дать не может
а 0 + 0 - будет число.

зато в первом варианте опять таки проблемы с пустым множеством
:)
77 Повелитель
 
13.02.13
14:17
(75)
Упрощенный запрос я привел в (46)
78 mr_K
 
13.02.13
14:21
А чтобы тогда не обсудить разницу СУММА(поле1 + поле2) и СУММА(поле1) + СУММА(поле2)?
79 Как страшно жить
 
13.02.13
14:24
(78) баян
80 Darklight
 
13.02.13
14:37
(76)Кстати, по-моему может, т.к.
1. Когда выборка пустая - будет NULL
2. Когда выборка не пустая, но все значения в суммируемом поле  есть NULL - то в результате тоже будет NULL
Кажется так.
(78)Ну мы тут обработку NULL обсуждали
81 Humandra
 
13.02.13
14:41
(80) хм. возможно вы и правы :)
но тогда оба варианта неверны :) и надо тот самый "100% надежный" - обернуть ЕСТЬNULL обе части и еще и снаружи
82 mikecool
 
13.02.13
14:45
насколько мне помнится результаты
sum(Isnull()) и Isnull(sum()) могут быть разными в разных субд
83 Повелитель
 
13.02.13
14:48
(82) Вот нам в этой теме только этого и нехватало ))))))
84 mikecool
 
13.02.13
14:49
(83) а, тут уже стеб.. я думал еще по теме...
85 Повелитель
 
13.02.13
14:52
(84) Нет тут стеба.
Просто уже более менее пришли к выводу. А если эту рассматривать с учетом разных СУБД, то спор будет вечным.
86 Humandra
 
13.02.13
14:53
(82) ну, в оракле и скуле вроде бы одинаково, насколько помню

по моему, такое поведение агрегатных функций - стандарт
но за PostgreSQL и DB2 не скажу, конечно...
87 Humandra
 
13.02.13
14:53
(86) стандарт - я имею в виду ANSI
88 mikecool
 
13.02.13
14:54
(86) не помню, могу наврать, но кажется оракуль ругался на нул в агрегате, но это кажется 8й был
для постгри - прямым не проверял, а из 1с - съедается нормально
89 mikecool
 
13.02.13
14:55
(87) а оракуль разве на анси стандарте?
90 Humandra
 
13.02.13
14:56
(88) не, насчет оракла точно - 5 лет на нем программила именно на такой конструции как 1 из (0)

(89) ну, часть какую-то соблюдают :)
91 mikecool
 
13.02.13
14:59
(90) а я его уже лет 8-9 не видел ))
92 Humandra
 
13.02.13
14:59
(89) 9i поддерживал 99-й стандарт
с небольшими отклонениями
точнее даже - с расширениями, я бы сказала
93 Humandra
 
13.02.13
15:00
(91) да я тоже уже давно с ним не работаю. Года 3 примерно.
94 Darklight
 
13.02.13
15:21
(81)Почему тогда оба не верны? - первый вариант в любом случае отработает корректно (для данного агрегата); а я не припомню ни одной БД, где агрегаты ругались на NULL в соурсных данных. Если только свои собственные агрегатные функции писать (но 1С это не умеет).
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший