Имя: Пароль:
1C
1С v8
Помогите с запросом
,
0 Grek404
 
27.09.18
11:51
ВЫБРАТЬ
    ЗапасыНаСкладахОстатки.Номенклатура КАК Номенклатура,
    ЗапасыНаСкладахОстатки.Характеристика КАК Характеристика,
    ЗапасыНаСкладахОстатки.СтруктурнаяЕдиница КАК СтруктурнаяЕдиница,
    ЗапасыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток,
    ЗапасыНаСкладахОстатки.Партия КАК Партия
ПОМЕСТИТЬ Остатки
ИЗ
    РегистрНакопления.ЗапасыНаСкладах.Остатки(&Период, ) КАК ЗапасыНаСкладахОстатки
ГДЕ
    ЗапасыНаСкладахОстатки.Номенклатура = &Номенклатура
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ЕСТЬNULL(Остатки.Номенклатура, ЗапасыНаСкладах.Номенклатура) КАК Номенклатура,
    ЕСТЬNULL(Остатки.Характеристика, ЗапасыНаСкладах.Характеристика) КАК Характеристика,
    ЕСТЬNULL(Остатки.Партия, ЗапасыНаСкладах.Партия) КАК Партия,
    ЕСТЬNULL(Остатки.СтруктурнаяЕдиница, ЗапасыНаСкладах.СтруктурнаяЕдиница) КАК СтруктурнаяЕдиница,
    ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК КоличествоОстаток,
    ЕСТЬNULL(ЗапасыНаСкладах.Количество, 0) КАК Продажи
ИЗ
    Остатки КАК Остатки
        ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.ЗапасыНаСкладах КАК ЗапасыНаСкладах
        ПО Остатки.СтруктурнаяЕдиница = ЗапасыНаСкладах.СтруктурнаяЕдиница
            И Остатки.Номенклатура = ЗапасыНаСкладах.Номенклатура
            И Остатки.Характеристика = ЗапасыНаСкладах.Характеристика
            И Остатки.Партия = ЗапасыНаСкладах.Партия
ГДЕ
    ЗапасыНаСкладах.Период МЕЖДУ &НачДата И &КонДата
    И (ЗапасыНаСкладах.Регистратор ССЫЛКА Документ.ЧекККМ
            ИЛИ ЗапасыНаСкладах.Регистратор ССЫЛКА Документ.РасходныйОрдер)
    И ЗапасыНаСкладах.Номенклатура = &Номенклатура
1 Mankubus
 
27.09.18
11:52
(0) в чем вопрос то?
2 Grek404
 
27.09.18
11:53
На выходе данные все правильные, вот только не все.
СтруктурныеЕдиницы с остатками, но без движений регистраторов не отображаются.
3 catena
 
27.09.18
11:54
(2)Потому что не фиг накладывать условия на левую таблицу. Не может быть NULL между какими-то датами.
4 Grek404
 
27.09.18
11:59
(3) Так ЗапасыНаСкладах правая таблица
5 VladZ
 
27.09.18
12:03
(4) Речь про то, что ты наложил условие ЗапасыНаСкладах.Период МЕЖДУ &НачДата И &КонДата

Говоря проще: показать те данные, по которым есть движения. А теперь спрашиваешь почему не все данные.

Ты сам понимаешь, что делаешь?
6 VladZ
 
27.09.18
12:04
За подобные конструкции:

РегистрНакопления.ЗапасыНаСкладах.Остатки(&Период, ) КАК ЗапасыНаСкладахОстатки
ГДЕ
    ЗапасыНаСкладахОстатки.Номенклатура = &Номенклатура

в некоторых фирмах тебе просто скажут "не стоит так делать". А в некоторых сделают тебе "пожизненный эцих с гвоздями".
7 Grek404
 
27.09.18
12:07
(6) Если не трудно, объясни.
8 VladZ
 
27.09.18
12:15
ВЫБРАТЬ
    ОстатокСумма
ИЗ
        РегистрНакопления.Запасы.Остатки(, Товар = &Товар)
9 Redkiy
 
27.09.18
12:15
10 Grek404
 
28.09.18
05:38
(8) Большое спасибо. Учту.
11 Grek404
 
28.09.18
05:39
(9) Огромное спасибо. Очень познавательно.
12 Grek404
 
28.09.18
08:07
Еще вопросик. Условие накладывать на реквизит (не индексируется) регистра тоже не айс?
13 Grek404
 
28.09.18
08:13
(12) Херню сказал :)
14 catena
 
28.09.18
08:15
(12)Зависит от задачи. Условие на реквизит в параметрах таблицы и в условиях запроса могут дать абсолютно разный результат.
15 evorle145
 
28.09.18
08:51
(14) приведи ка пример. Какое можно написать условие в параметрах, что оно даст иной результат в условиях?
16 catena
 
28.09.18
08:58
(15)
ВЫБРАТЬ
    КОЛИЧЕСТВО(Р.Физлицо) КАК Физлицо
ИЗ
    РегистрСведений.РаботникиОрганизаций.СрезПоследних(, ПричинаИзмененияСостояния <> ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Увольнение)) КАК Р
    ;
ВЫБРАТЬ
    КОЛИЧЕСТВО(Р.Физлицо) КАК Физлицо
ИЗ
    РегистрСведений.РаботникиОрганизаций.СрезПоследних(, ) КАК Р
Где ПричинаИзмененияСостояния <> ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Увольнение)
17 Фрэнки
 
28.09.18
09:03
(16) не подвергаю сомнению, что на эти грабли наступили :)

Но интересно, а есть какое-то развернутое/разжеванное объяснение причины, почему такие примеры возвращают разные результаты? Если не слишком затруднит, пожалуйста
18 evorle145
 
28.09.18
09:14
(16) точно. Благодарю.
(17) да, казалось бы и там и там условие где выполнится первым. НО! Первом случае выберутся последние записи из тех что не уволены, и потом будет группировка по кол-ву. А Во втором случае выберутся просто последние записи (не факт что уволенные), потом наложится на это условие отбор и потом группировка. Нарисуйте себе две записи: принят 01012017 Уволен 01012018 и поймете что результат разный=)
19 Grek404
 
28.09.18
09:23
ВЫБРАТЬ
    ЗапасыНаСкладахОстатки.Номенклатура КАК Номенклатура,
    ЗапасыНаСкладахОстатки.Характеристика КАК Характеристика,
    ЗапасыНаСкладахОстатки.СтруктурнаяЕдиница КАК Склад,
    ЗапасыНаСкладахОстатки.КоличествоОстаток КАК ОстатокНачало,
    ЗапасыНаСкладахОстатки.Партия КАК Партия
ПОМЕСТИТЬ ТаблОстатки
ИЗ
    РегистрНакопления.ЗапасыНаСкладах.Остатки(&НачДата, Номенклатура = &Номенклатура) КАК ЗапасыНаСкладахОстатки
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ЗапасыНаСкладахОстатки.Номенклатура КАК Номенклатура,
    ЗапасыНаСкладахОстатки.Характеристика КАК Характеристика,
    ЗапасыНаСкладахОстатки.СтруктурнаяЕдиница КАК Склад,
    ЗапасыНаСкладахОстатки.КоличествоОстаток КАК ОстатокКонец,
    ЗапасыНаСкладахОстатки.Партия КАК Партия
ПОМЕСТИТЬ ТаблОстаткиКонец
ИЗ
    РегистрНакопления.ЗапасыНаСкладах.Остатки(&КонДата, Номенклатура = &Номенклатура) КАК ЗапасыНаСкладахОстатки
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ЕСТЬNULL(ТаблОстатки.Номенклатура, ТаблОстаткиКонец.Номенклатура) КАК Номенклатура,
    ЕСТЬNULL(ТаблОстатки.Характеристика, ТаблОстаткиКонец.Характеристика) КАК Характеристика,
    ЕСТЬNULL(ТаблОстатки.Склад, ТаблОстаткиКонец.Склад) КАК Склад,
    ЕСТЬNULL(ТаблОстатки.Партия, ТаблОстаткиКонец.Партия) КАК Партия,
    СУММА(ТаблОстатки.ОстатокНачало) КАК ОстатокНачало,
    СУММА(ТаблОстаткиКонец.ОстатокКонец) КАК ОстатокКонец
ПОМЕСТИТЬ ТаблицаОстатков
ИЗ
    ТаблОстатки КАК ТаблОстатки
        ПОЛНОЕ СОЕДИНЕНИЕ ТаблОстаткиКонец КАК ТаблОстаткиКонец
        ПО ТаблОстатки.Склад = ТаблОстаткиКонец.Склад
            И ТаблОстатки.Номенклатура = ТаблОстаткиКонец.Номенклатура
            И ТаблОстатки.Характеристика = ТаблОстаткиКонец.Характеристика
            И ТаблОстатки.Партия = ТаблОстаткиКонец.Партия

СГРУППИРОВАТЬ ПО
    ТаблОстатки.Номенклатура,
    ТаблОстатки.Характеристика,
    ТаблОстатки.Склад,
    ТаблОстатки.Партия,
    ТаблОстаткиКонец.Номенклатура,
    ТаблОстаткиКонец.Характеристика,
    ТаблОстаткиКонец.Склад,
    ТаблОстаткиКонец.Партия
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ЗапасыНаСкладах.СтруктурнаяЕдиница КАК Склад,
    ЗапасыНаСкладах.Номенклатура КАК Номенклатура,
    ЗапасыНаСкладах.Характеристика КАК Характеристика,
    ЗапасыНаСкладах.Партия КАК Партия,
    ЗапасыНаСкладах.Количество КАК КоличествоОборот
ПОМЕСТИТЬ ТаблПродажи
ИЗ
    РегистрНакопления.ЗапасыНаСкладах КАК ЗапасыНаСкладах
ГДЕ
    ЗапасыНаСкладах.Период МЕЖДУ &НачДата И &КонДата
    И (ЗапасыНаСкладах.Регистратор ССЫЛКА Документ.ЧекККМ
            ИЛИ ЗапасыНаСкладах.Регистратор ССЫЛКА Документ.РасходныйОрдер)
    И ЗапасыНаСкладах.Номенклатура = &Номенклатура
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ЕСТЬNULL(ТаблицаОстатков.Номенклатура, ТаблПродажи.Номенклатура) КАК Номенклатура,
    ЕСТЬNULL(ТаблицаОстатков.Характеристика, ТаблПродажи.Характеристика) КАК Характеристика,
    ЕСТЬNULL(ТаблицаОстатков.Склад, ТаблПродажи.Склад) КАК Склад,
    ЕСТЬNULL(ТаблицаОстатков.Партия, ТаблПродажи.Партия) КАК Партия,
    СУММА(ТаблицаОстатков.ОстатокНачало) КАК ОстатокНачало,
    СУММА(ТаблицаОстатков.ОстатокКонец) КАК ОстатокКонец,
    СУММА(ТаблПродажи.КоличествоОборот) КАК КоличествоОборот
ИЗ
    ТаблицаОстатков КАК ТаблицаОстатков,
        ПОЛНОЕ СОЕДИНЕНИЕ ТаблПродажи КАК ТаблПродажи
        ПО ТаблицаОстатков.Склад = ТаблПродажи.Склад
            И ТаблицаОстатков.Номенклатура = ТаблПродажи.Номенклатура
            И ТаблицаОстатков.Характеристика = ТаблПродажи.Характеристика
            И ТаблицаОстатков.Партия = ТаблПродажи.Партия

СГРУППИРОВАТЬ ПО
    ТаблицаОстатков.Номенклатура,
    ТаблицаОстатков.Характеристика,
    ТаблицаОстатков.Склад,
    ТаблицаОстатков.Партия,
    ТаблПродажи.Склад,
    ТаблПродажи.Номенклатура,
    ТаблПродажи.Характеристика,
    ТаблПродажи.Партия


А вот такой запрос тоже кривой? :)
20 Grek404
 
28.09.18
09:25
(19) Пробую в отчете этот запрос - остатки не правильные
Пробую в Консоли запросов - вся итоговая таблица верна.

В чем разница?
21 Grek404
 
28.09.18
09:27
(20) Отчет СКД - остатки не верные, а продажи правильные.
В консоли всё правильно
22 catena
 
28.09.18
09:37
(17)Лично не наступала, но люблю давать на собеседованиях :)
23 catena
 
28.09.18
09:39
(21)Проблема либо в параметрах, либо в оптимизаторе СКД. Нужно вытащить итоговый запрос СКД и сравнить с тем вариантом, который запускаете в консоли.
24 Фрэнки
 
28.09.18
09:47
(23) (18) Спасибо, ок. Я понял.
И посмотрел откуда это взято, после ваших разъяснений.

Разность получается из-за того, что там в конфигурации сделано. Это характерно для конкретного примера - это из ЗУП 2.5 получается. В 3.1 такого примера с этим регистром не сделаешь, т.к. 3.1 этого регистра просто нет. Ну может другие есть - не проверил, не попались на глаза

Проблема в том, что в структуре регистра поле ПричинаИзмененияСостояния = это реквизит! Я даже немного удивлен, что в параметрах вызова таблицы СрезПоследних разрешено ставить условие отбора на значения Реквизита, а не по Измерениям. Если бы это поле было Измерением, то результат у обоих способов получения данных был бы одинаков.
25 Grek404
 
28.09.18
09:58
(23) Я полностью весь запрос копирую. :)
26 Salimbek
 
28.09.18
09:58
(6) и (9) Бывает и так, что куча условий (с подзапросами, или,например, к составным реквизитам), засунутые внутрь параметров таблицы, в итоге на стороне SQL разворачиваются в монструознейший код, на котором оптимизатор SQL-я отваливается и начинает тупой скан. И потому иногда выгоднее делать выборку с минимальными условиями в параметрах, а прочие условия накладывать в секции ГДЕ.
27 catena
 
28.09.18
10:12
(24)Я выше и писала, что с реквизитами надо быть осторожнее. Если понимать, как происходит выборка, пригодится может и тот и тот способ.

(25)Еще раз: запрос и результирующий запрос в СКД могут сильно отличаться. Она на выходе может подставлять свои, не задуманные пользователем, параметры, или отрезать поля промежуточных таблиц, которые, по ее мнению, не участвуют в результате.
28 evorle145
 
28.09.18
10:24
(24) "Если бы это поле было Измерением, то результат у обоих способов получения данных был бы одинаков" Уверен? =) На сколько я понял    catena , то как раз словим разницу.
   catena, рассуди плиз
29 Grek404
 
28.09.18
10:34
(27) Параметры удалил и прописал заново. Результат изменился. Почти всё правильно стало :)

Я так понимаю на данном примере надо отказаться от СКД?
30 Grek404
 
28.09.18
10:40
(27) Или просто надо всё с чистого листа переписать?
31 evorle145
 
28.09.18
10:54
(30) друг, я вообще не понимаю, зачем ты таблицу остатков соединяешь ПОЛНЫМ соединением с таблицей продаж... какой там результат получается - мне не понять...
32 catena
 
28.09.18
11:02
(28)Нет, с измерениями все ровно :) Судя по мануалу, разница только в производительности.
33 Пробел
 
28.09.18
11:04
(24) Если я правильно понял, машина отработает так:

У нас есть две записи по одному сторуднику:

принят 01012017
Уволен 01012018

Первый запрос сначала выкинет запись "уволен", потом возьмет последнюю запись из оставшихся. Получится КОЛИЧЕСТВО(Физлицо) = 1.

Второй запрос сначала возьмет последнюю запись, которая "уволен", потом отбором помножит ее на ноль. Получим КОЛИЧЕСТВО(Физлицо) = 0.
34 Фрэнки
 
28.09.18
11:06
(33) ну да, так оно и будет, потому что состояние "уволен" сидит именно в реквизитах записей, и по срезу последних без параметров именно она и вернется.
35 evorle145
 
28.09.18
11:07
(33) Именно! Это я говорил, но меня видно не поняли. Не знаю, почему (24) привязался к измерениям и реквизитам. Не важно, измерение или реквизит, отработает так, как написано в (33).
36 Фрэнки
 
28.09.18
11:08
(35) важно!
37 evorle145
 
28.09.18
11:09
(36) а, все, да, дошло! Извините за (35).
38 Пробел
 
28.09.18
11:36
(37) До меня вроде тоже дошло) Только это сложно сформулировать по простому х)

Отбор по измерению откидывает в сторону ключи и соответствующие им наборы записей, а отбор по реквизиту в параметрах виртуальной таблицы выкидывает отдельные записи из каждого набора.

А отбор в "ГДЕ" это вообще другая история, поскольку применяется уже не к виртуальной таблице а к результирующей.
39 evorle145
 
28.09.18
11:46
(38) то есть получается, что если это реквизит - то получим один результат, если это измерение - то другой?

То есть берем виртуальную таблицу и ставим в нее отбор:

РегистрСведений.РаботникиОрганизаций.СрезПоследних(, ПричинаИзмененияСостояния <> ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Увольнение))

Получаем результат и думаем:

будет ли одинаковым отбор, если ПричинаИзмененияСостояния является реквизитом/измерением ?

Не кажется ли вам, что когда будет формироваться виртуальная таблица, то она в любом случае сначала выкинет записи где измерение/реквизит не соответствует условию, а уж потом возьмет срез последних..

Верно? вот (36)  утверждает что разница будет...
40 Фрэнки
 
28.09.18
11:55
(39) ну я же неоднократно на эти грабли наступал.
Просто здесь в ветке решили разобрать причины по косточкам, так сказать. И после проверки, что ПричинаИзмененияСостояния именно реквизит - все стало предельно ясным.
41 Фрэнки
 
28.09.18
11:58
РегистрыСведений и СрезПоследних - сам смысл их использования в наличии полей Измерение, Ресурс, Реквизит
42 Пробел
 
28.09.18
12:15
(39) Да, будет разница.

пусть у нас будет периодический регистр сотрудник - состояние - дата, где сотрудник - измерение, состояние - реквизит, а дата - период.

Вася - принят - 01012017
Вася - в запое - 01032017
Вася - уволен - 01042017

Петя - принят - 01022017
Петя - на больничном - 01032017
Петя - уволен - 01062017

Отбор по измерению "не равно Вася" уберет из результата соответствующий набор записей, оставив остальные наборы полными. Отбор по реквизиту "не равно уволен", оставит все наборы, но выкинет из каждого по записи.
43 catena
 
28.09.18
12:46
(42)Вот в таком регистре как раз будет удобно выбирать с отбором в виртуальной таблице, чтобы посмотреть, что было с Васей и Петей перед увольнением))
44 Grek404
 
28.09.18
12:49
(31) Задача такая нужна колонка остатки на начало периода, продажи за период, остатки на конец периода.

Но продажи только расходные ордера и чекиККМ.

И плюс к тому что в базе разрешена продажа в минус.

И так как в обеих таблицах возможно разное количество строк, мне надо чтоб они все показались.

Блин. Так если я сначала соединяю остатки до и после, то полюбому все строки уже будут. Туплю. Следует что продажи можно левым соединением дописать.
45 evorle145
 
28.09.18
12:53
(42) Спс. Согласен. Убедил окончательно.
46 MuxaH
 
28.09.18
12:54
(44) Такое проще через объединение наборов сделать, если СКД конечно.
47 evorle145
 
28.09.18
12:58
пусть у нас будет периодический регистр сотрудник - состояние - дата, где сотрудник - измерение, состояние - тоже измерение, а дата - период.

Вася - принят - 01012017
Вася - в запое - 01032017
Вася - уволен - 01042017

Петя - принят - 01022017
Петя - на больничном - 01032017
Петя - уволен - 01062017

срезпоследних с Отбором по измерению "состояние не не равно уволен " даст результат:

Вася - в запое - 01032017
Петя - на больничном - 01032017 ?
48 catena
 
28.09.18
13:11
(47)Нет, будет пустой результат, т.к. в данном случае состояние входит в ключ среза последних.
49 Grek404
 
28.09.18
13:19
(46) Огромное спасибо. Помогло. Все данные правильные. :)))))))))
50 evorle145
 
28.09.18
13:21
(48) то есть виртуальная таблица строится таким образом, что сначала получает последние записи по всем измерениям:

Вася - уволен - 01042017
Петя - уволен - 01062017

И только потом наложит отбор по измерению "Состояние" несмотря на то что отбор стоит в параметрах виртуальной таблицы?
51 catena
 
28.09.18
13:22
(50)Для измерений да.
52 evorle145
 
28.09.18
13:25
(51) понял... не знал.. просто вроде говорили всегда, что писать  отборы нужно в параметрах виртуальной таблицы, чтобы она сразу отобрала нужное... я думал что это касается и измерений тоже.. А оказывается что по измерениям она все-таки выберет все последние записи по ключу измерений, а уж потом отбор наложит...