Имя: Пароль:
1C
1С v8
Как правильно сделать в запросе проверку на NULL ?
, ,
0 Ткачев
 
04.09.12
08:21
1. СУММА(ЕСТЬNULL(РасходнаяНакладнаяУслуги.Сумма, 0)) 71% (10)
2. ЕСТЬNULL(СУММА(РасходнаяНакладнаяУслуги.Сумма), 0) 29% (4)
Всего мнений: 14

Сабж
1 golden-pack
 
04.09.12
08:23
А разве есть варианты ?
2 shuhard
 
04.09.12
08:23
(0) оба варианта в топку
3 Ткачев
 
04.09.12
08:24
(2)Тогда как ?
4 Ткачев
 
04.09.12
08:27
Весь запрос:

       Запрос = Новый Запрос("
       |ВЫБРАТЬ ПЕРВЫЕ 1
       |    КонвертацияДС.Дата КАК НачДата
       |ПОМЕСТИТЬ ДатаНачалаСмены
       |ИЗ
       |    Документ.КонвертацияДС КАК КонвертацияДС
       |ГДЕ
       |    КонвертацияДС.Проведен = ИСТИНА
       |
       |УПОРЯДОЧИТЬ ПО
       |    НачДата УБЫВ
       |;
       |
       |////////////////////////////////////////////////////////////////////////////////
       |ВЫБРАТЬ ПЕРВЫЕ 1
       |    РасходнаяНакладная.Дата КАК КонДата
       |ПОМЕСТИТЬ ДатаОкончанияСмены
       |ИЗ
       |    Документ.РасходнаяНакладная КАК РасходнаяНакладная
       |ГДЕ
       |    РасходнаяНакладная.Проведен = ИСТИНА
       |
       |УПОРЯДОЧИТЬ ПО
       |    КонДата УБЫВ
       |;
       |
       |////////////////////////////////////////////////////////////////////////////////
       |ВЫБРАТЬ
       |    ЕСТЬNULL(СУММА(РасходнаяНакладнаяУслуги.Сумма), 0) КАК Сумма,
       |    МИНИМУМ(ДатаНачалаСмены.НачДата) КАК НачДата,
       |    МАКСИМУМ(ДатаОкончанияСмены.КонДата) КАК КонДата
       |ИЗ
       |    Документ.РасходнаяНакладная.Услуги КАК РасходнаяНакладнаяУслуги,
       |    ДатаНачалаСмены КАК ДатаНачалаСмены,
       |    ДатаОкончанияСмены КАК ДатаОкончанияСмены
       |ГДЕ
       |    РасходнаяНакладнаяУслуги.Ссылка.Дата > ДатаНачалаСмены.НачДата
       |    И РасходнаяНакладнаяУслуги.Номенклатура = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПополнениеБалансаВодителей)
       |    И РасходнаяНакладнаяУслуги.Ссылка.Проведен = ИСТИНА");
5 andrewks
 
04.09.12
08:28
сумма() зачем?
6 Ткачев
 
04.09.12
08:30
(5)Надо получить сумму с начала смены и по конец смены.
7 MatrosoV AleXXXand_R
 
04.09.12
08:30
так если что правильнее при любых раскладах

СУММА(ЕСТЬNULL(РасходнаяНакладнаяУслуги.Сумма, 0))
8 Гобсек
 
04.09.12
08:31
Вместо

РасходнаяНакладная.Проведен = ИСТИНА

обычно пишут просто

РасходнаяНакладная.Проведен
9 Рэйв
 
04.09.12
08:31
Иначе при нулл вылетит по ошибке

СУММА(ЕСТЬNULL(РасходнаяНакладнаяУслуги.Сумма, 0))
10 MatrosoV AleXXXand_R
 
04.09.12
08:32
"       |ИЗ
       |    Документ.РасходнаяНакладная.Услуги КАК РасходнаяНакладнаяУслуги,
       |    ДатаНачалаСмены КАК ДатаНачалаСмены,
       |    ДатаОкончанияСмены КАК ДатаОкончанияСмены"

вот это что? Почему не соединением с таблицами?
11 Гобсек
 
04.09.12
08:32
.

СУММА(ЕСТЬNULL(РасходнаяНакладнаяУслуги.Сумма, 0))
12 andrewks
 
04.09.12
08:33
запрос в (4) нерабочий
13 bodri
 
04.09.12
08:33
так.

СУММА(ЕСТЬNULL(РасходнаяНакладнаяУслуги.Сумма, 0))
14 Ткачев
 
04.09.12
08:33
(10)А соединение не надо, надо даты начала смены и конца.
15 ДенисЧ
 
04.09.12
08:35
Любое число + NULL == NULL
Так что

СУММА(ЕСТЬNULL(РасходнаяНакладнаяУслуги.Сумма, 0))
16 andrewks
 
04.09.12
08:36
у меня встречный вопрос: а откуда вообще берётся null?
17 mehfk
 
04.09.12
08:37
Посмотрел в коде УПП оба варианта используются.
ISNULL(SUM(Выражение),0) должен быть быстрее

ЕСТЬNULL(СУММА(РасходнаяНакладнаяУслуги.Сумма), 0)
18 MatrosoV AleXXXand_R
 
04.09.12
08:38
(16) в его случае не в каком
19 andrewks
 
04.09.12
08:40
(18) вот о том и речь. а ответ на сабжевый вопрос зависит от конкретной задачи
20 Ткачев
 
04.09.12
08:42
(18)С чего ради, этой номенклатуры может и не быть в смене.
21 andrewks
 
04.09.12
08:43
(20) какой - этой?
22 Ткачев
 
04.09.12
08:44
(21)|    И РасходнаяНакладнаяУслуги.Номенклатура = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПополнениеБалансаВодителей)
23 Рэйв
 
04.09.12
08:45
(16)При левом соединении Номенклатуры с чем то где суммы, если в таблице сумм нет номенклатуры - будет NULL
24 andrewks
 
04.09.12
08:46
(22) и? продолжай
25 MatrosoV AleXXXand_R
 
04.09.12
08:49
(22) проверка на ЕстьNULL в твоем случае не нужна

Она нужна к примеру вот в таком запросе

ВЫБРАТЬ
  Таблица1.Реквизит1,
  СУММА(Таблица1.Сумма) КАК Сумма1,
  СУММА(ЕСТЬNULL(Таблица2.Сумма, 0)) КАК Сумма2
ИЗ Таблица1 КАК Таблица1

ЛЕВОЕ СОЕДИНЕНИЕ Таблица2 КАК Таблица2
ПО Таблица1.Реквизит = Таблица2.Реквизит1

если что - запрос набрал руками. Вообщем, думаю что из него понятно, что из Таблица2 можем получить сумму NULL и преобразовываем ее в 0, а из Таблица1 в данном случае мы получаем всегда число - и ЕСТЬNULL просто не нужна
26 andrewks
 
04.09.12
08:49
(23) где здесь левое соединение?
27 andrewks
 
04.09.12
08:49
одно из двух - либо вы загнались, либо я
28 Рэйв
 
04.09.12
08:50
(26)Здесь - это где?
29 Рэйв
 
04.09.12
08:50
Я описал возможный вариант полученя нулла в сумме
30 Ткачев
 
04.09.12
08:51
(25)Но вылазит ошибка, СУММА(РасходнаяНакладнаяУслуги.Сумма) КАК Сумма = NULL
31 acsent
 
04.09.12
08:51
если запрос вернет 0 записей то оба варианта ддут NULL
32 andrewks
 
04.09.12
08:51
(29) мы здесь вроде как конкретный запрос обсуждаем
33 Рэйв
 
04.09.12
08:52
(31)Тогда вообзе будет пустой результат без всяких нулов
34 Ткачев
 
04.09.12
08:52
+(30)Если что раньше ЕСТЬNULL тут не стоял.
35 andrewks
 
04.09.12
08:52
(33) во!
36 acsent
 
04.09.12
08:52
(33) нет ибо агрегат
37 Рэйв
 
04.09.12
08:52
(34)аа...Пропустил (4)
:-)
38 Ненавижу 1С
 
гуру
04.09.12
08:53
никакой разницы, но я за ЕСТЬNULL(СУММА(...),0)

ЕСТЬNULL(СУММА(РасходнаяНакладнаяУслуги.Сумма), 0)
39 andrewks
 
04.09.12
08:53
(38) "никакой разницы"  разница есть
40 mehfk
 
04.09.12
08:54
41 Ткачев
 
04.09.12
08:54
(37)Раньше не было, я его сейчас поставил и задумался где же его лучше поставить до СУММА или после.
42 mehfk
 
04.09.12
08:54
43 Ткачев
 
04.09.12
08:56
(38)Я тоже, здесь либо есть NULL, либо его нету.
44 Ненавижу 1С
 
гуру
04.09.12
09:04
(39) только если выборка пустая, то есть
45 Анцеранана
 
04.09.12
09:04
(0) Имхо предпочтительнее первый вариант если без группировок ниже, а если ниже написано ГРУППИРОВАТЬ то второй.
не голосую!
46 Ткачев
 
04.09.12
09:07
Господа вариант1 работает, а вариант2 дает.
{Форма.Форма.Форма(67)}: Преобразование значения к типу Число не может быть выполнено
       СуммаТоваровУслуг = КассаСуммаВККМ - БалансВодителей;

   Результат = Запрос.Выполнить().Выбрать();
   Если Результат.Следующий() Тогда
       БалансВодителей = Результат.Сумма;
       СуммаТоваровУслуг = КассаСуммаВККМ - БалансВодителей;
   КонецЕсли;
47 andrewks
 
04.09.12
09:10
(44) не только. возьмём, например, выборку из таблицы, где во всех строках Null
48 andrewks
 
04.09.12
09:14
ы-ы-ы :-)  попытка на DB2 просуммировать табличку из одних нуллов как isnull(sum(),0) завершилась успешно, результата - 0, а вот с sum(isnull(,0))  -вывалило 1С с ошибкой SDBL
49 Светлый Гений
 
04.09.12
09:28
Конечно 2

СУММА(ЕСТЬNULL(РасходнаяНакладнаяУслуги.Сумма, 0))
50 Ткачев
 
04.09.12
09:48
Если Сумма = NULL, тогда НачДата и КонДата тоже = NULL, можно как то сделать что бы они были правильно полученными из временных таблиц ?
51 spock
 
04.09.12
09:55
всех голосовавших за вариант 1 срочно на переаттестацию

СУММА(ЕСТЬNULL(РасходнаяНакладнаяУслуги.Сумма, 0))
52 Ткачев
 
04.09.12
10:00
(49)(51)->(46)
53 spock
 
04.09.12
10:05
(52)так изучать запросы тебе нужно, твой запрос из (4) неявно преобразован в full join с соответсвующими выводами.
54 spock
 
04.09.12
10:08
+53 запрос в (4) вообще работает так, как ты задумывал?
55 SherifSP
 
04.09.12
10:09
Правильнее

СУММА(ЕСТЬNULL(РасходнаяНакладнаяУслуги.Сумма, 0))
56 mehfk
 
04.09.12
10:15
(51) Типовые смотрел?
57 Ненавижу 1С
 
гуру
04.09.12
10:16
(47) уговорил))
58 andrewks
 
04.09.12
10:17
(53) какой ещё фулл джойн? кросс джойн, наверное?
59 andrewks
 
04.09.12
10:20
+(58) попробуй соединить через запятую пустую таблицу
60 andrewks
 
04.09.12
10:22
я так понимаю, "," = "inner join on true"
61 fisher
 
04.09.12
10:22
(0) Сумма вернет NULL, только если во всех строках было NULL, т.к. по дефолту NULL при агрегации игнорируется. Т.е. по результату оба варианты равнозначны. Но вообще, если не ошибаюсь, в сиквеле это поведение можно менять. Так что теоретически второй вариант однозначнее. На практике же - монопенисуально.

СУММА(ЕСТЬNULL(РасходнаяНакладнаяУслуги.Сумма, 0))
62 Schwonder
 
04.09.12
10:47
(61) Таки не монопенисуально, в Вашем случае, каждое сумма будет проверяться на NULL, а в случае "ЕСТЬNULL(СУММА(РасходнаяНакладнаяУслуги.Сумма), 0)" только результат. Какбэ производительность!!!

ЕСТЬNULL(СУММА(РасходнаяНакладнаяУслуги.Сумма), 0)
63 Ткачев
 
04.09.12
10:50
Кто за 2 объясните тогда почему вываливается в ошибку см.(46), Результат.Сумма там равно NULL
64 Sammo
 
04.09.12
10:55
(63) Емнип, была фишка - в случае, когда
1. В результате запроса только значения агрегатов (функций)
2. На входе были NULL
В этом случае Выборка.Количество() = 1 и в там строки с нулами
Решение - обрабатывать такую ситуацию или добавить поле. Например, добавить в результат выборки РасходнаяНакладнаяУслуги.Номенклатура
65 rs_trade
 
04.09.12
10:57
очевидно же что первый вариант будет 0 давать если будет хоть один нулл

СУММА(ЕСТЬNULL(РасходнаяНакладнаяУслуги.Сумма, 0))
66 Reset
 
04.09.12
11:02
Второй вараинт даст null при пустой выборке

ЕСТЬNULL(СУММА(РасходнаяНакладнаяУслуги.Сумма), 0)
67 Schwonder
 
04.09.12
11:02
(65) Это в чем же Ваша очевидность заключается?
68 ssh2006
 
04.09.12
11:05
(66) +1
69 spock
 
04.09.12
11:06
(58)да-да, cross, это я пургу прогнал сперепугу
70 Reset
 
04.09.12
11:07
(62) Очевидно, (с) :) что проверка на null производится в обоих случаях. В одном из случаев просто можно указать, как его интерпретировать, во втром это по умолчанию
71 andrewks
 
04.09.12
11:12
(65) нифига
72 rs_trade
 
04.09.12
11:13
(65) вру. sum null-ы игнорит
73 Schwonder
 
04.09.12
11:24
(72) Золотые слова Юрий Венедиктович (ц)
74 spock
 
04.09.12
11:48
(63)у какие-то временные таблицы пустые.