Вход | Регистрация


1С:Предприятие :: 1С:Предприятие 8 общая

Помогите с запросом

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

////////////////////////////////////////////////////////////////////////////////

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

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

Ты сам понимаешь, что делаешь?
   VladZ
 
6 - 27.09.18 - 12:04
За подобные конструкции:
РегистрНакопления.ЗапасыНаСкладах.Остатки(&Период, ) КАК ЗапасыНаСкладахОстатки
ГДЕ
    ЗапасыНаСкладахОстатки.Номенклатура = &Номенклатура

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

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

////////////////////////////////////////////////////////////////////////////////

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

////////////////////////////////////////////////////////////////////////////////

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

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

////////////////////////////////////////////////////////////////////////////////

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

////////////////////////////////////////////////////////////////////////////////

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

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


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

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

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

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

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

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

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

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

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

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

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

А отбор в "ГДЕ" это вообще другая история, поскольку применяется уже не к виртуальной таблице а к результирующей.
   evorle145
 
39 - 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

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

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

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

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

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

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

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

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

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

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

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


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Рекламное место пустует