Имя: Пароль:
1C
1С v8
возможно ли сделать запрос лучше?
,
0 rchervak
 
18.09.15
13:20
Дали задачку на собеседовании.
Чет сначала затупил, и не правильно написал. а щас сел и быстренько навоял. но вот думаю можно ли более изящно придумать?

Возможно с "ОБЪЕДЕНИЕТЬ" будет более правильно? но я не смог придумать как

Задача:
есть СПРАВОЧНИК "Движение товаров" , с реквизитами:
1. Номенклатура
2. Склад
3. ВидДвижеия(приход/расход)
4. Количество
5. Дата

Условие: запрос должен делать выборку по &НачПериода и &Кон Периода

есть нюанс: нельзя использовать вложенные запросы и временные таблицы.

Нужно получить таблицу со значениями:

Номенклатура | Склад | НачОстаток | Приход | Расход | КонОстаток |

Вот решение:
ВЫБРАТЬ
    ДвиженияТоваров.Номенклатура,
    ДвиженияТоваров.Склад,
    СУММА(ВЫБОР
            КОГДА ДвиженияТоваров.дата <= &НачПериода
                ТОГДА ВЫБОР
                        КОГДА ДвиженияТоваров.ВидДвижения = ЗНАЧЕНИЕ(перечисление.ВидДвижения.приход)
                            ТОГДА ДвиженияТоваров.Количество
                        ИНАЧЕ -1 * ДвиженияТоваров.Количество
                    КОНЕЦ
            ИНАЧЕ 0
        КОНЕЦ) КАК НачальныйОстаток,
    СУММА(ВЫБОР
            КОГДА ДвиженияТоваров.дата > &НачПериода
                    И ДвиженияТоваров.дата < &КонПериода
                ТОГДА ВЫБОР
                        КОГДА ДвиженияТоваров.ВидДвижения = ЗНАЧЕНИЕ(перечисление.ВидДвижения.приход)
                            ТОГДА ДвиженияТоваров.Количество
                        ИНАЧЕ 0
                    КОНЕЦ
            ИНАЧЕ 0
        КОНЕЦ) КАК Приход,
    СУММА(ВЫБОР
            КОГДА ДвиженияТоваров.дата > &НачПериода
                    И ДвиженияТоваров.дата < &КонПериода
                ТОГДА ВЫБОР
                        КОГДА ДвиженияТоваров.ВидДвижения = ЗНАЧЕНИЕ(перечисление.ВидДвижения.расход)
                            ТОГДА ДвиженияТоваров.Количество
                        ИНАЧЕ 0
                    КОНЕЦ
            ИНАЧЕ 0
        КОНЕЦ) КАК Расход,
    СУММА(ВЫБОР
            КОГДА ДвиженияТоваров.дата <= &КонПериода
                ТОГДА ВЫБОР
                        КОГДА ДвиженияТоваров.ВидДвижения = ЗНАЧЕНИЕ(перечисление.ВидДвижения.приход)
                            ТОГДА ДвиженияТоваров.Количество
                        ИНАЧЕ -1 * ДвиженияТоваров.Количество
                    КОНЕЦ
            ИНАЧЕ 0
        КОНЕЦ) КАК Остаток
ИЗ
    Справочник.ДвиженияТоваров КАК ДвиженияТоваров

СГРУППИРОВАТЬ ПО
    ДвиженияТоваров.Номенклатура,
    ДвиженияТоваров.Склад
1 zhig75
 
18.09.15
13:23
Какая жесть, "справочник движения товаров".
2 Гёдза
 
18.09.15
13:23
(1) +100500
3 senior
 
18.09.15
13:24
да что ж сегодня за день такой)
4 Гёдза
 
18.09.15
13:25
пятница )))
5 Voffka
 
18.09.15
13:26
(0) Ты что в рарус Устраиваешься(-ился)?.... ой-ёй...
6 itlikbez
 
18.09.15
13:26
(1) Да ниче так задачка. Для собеседования самое то.
7 rchervak
 
18.09.15
13:26
запрос надо было на листочке написать.
8 GreatOne
 
18.09.15
13:26
(7) ты понимаешь что работодатель тебя троллил?
9 rchervak
 
18.09.15
13:27
(5) не. фикси в отдел разработки
10 itlikbez
 
18.09.15
13:27
(0) Нормально. Через "ОБЪЕДИНИТЬ" лучше не будет.
11 rchervak
 
18.09.15
13:28
(8) к чему бы это? обычная задачка на логику.
12 bootini
 
18.09.15
13:28
(7) Разрабатывать потом тоже на листочке нужно будет :)
13 Voffka
 
18.09.15
13:28
(12) И ЗП на листочке рассчитывать :)
14 senior
 
18.09.15
13:29
скажи я не пишу запросы я выполняю сразу в голове, и ответ выдаю на листочек
15 Voffka
 
18.09.15
13:29
(0) Беги от туда, детка!!!
16 rchervak
 
18.09.15
13:29
(15) меня и не взяли
17 Voffka
 
18.09.15
13:30
(16) Почему? Пятница?
18 rchervak
 
18.09.15
13:30
я как раз написал через объеденить))
19 Voffka
 
18.09.15
13:30
(16) Успокойси, значит умные там не нужны, а разносчики.
20 ADirks
 
18.09.15
13:31
в который раз убеждаюсь, восьмёрошники и запросы несовместимы...
этож надо, такое условие придумать "без вложенных запросов"
кстати, с UNION без вложенного запроса не получится.
21 Voffka
 
18.09.15
13:31
(18) А, это другое дело, тогда тебе фо франч сначала.
22 GreatOne
 
18.09.15
13:31
написал бы обработку по переносу всех значений этого справочника в РН. По второй кнопке богоугодный запрос в СКД
23 PLUT
 
18.09.15
13:32
(17) ТС затупил же (0), вот теперь тренируется на листочках запросы писать
24 NcSteel
 
18.09.15
13:33
(10) Будет лучше конечно. Если бы мне показали такой запрос, то я бы сильно задумался над приемом такого сотрудника.
25 NcSteel
 
18.09.15
13:33
(18) Через объеденить правильно
26 Tarlich
 
18.09.15
13:35
если я правильно понимаю начальный остаток можно (и нужно) ковырять из регистра
27 senior
 
18.09.15
13:36
(16) а че не взяли, запрос в принципе норм
28 GreatOne
 
18.09.15
13:36
(26) кэп, мы все тебя ждали!
29 Бледно Золотистый
 
18.09.15
13:36
(25) Без вложенного или временной табл. не сгруппируешь.
30 GreatOne
 
18.09.15
13:36
(27) не взяли, потому что за выполнения этого запроса,в принципе, взялись)
31 NcSteel
 
18.09.15
13:36
(26) Судя по требованию надо все на основании справочника делать
32 rchervak
 
18.09.15
13:37
(29) вот и у меня никак не получилось сгруппировать
может посоветуете как? если конечно можно
33 NcSteel
 
18.09.15
13:38
(29) За выбор когда надо расстреливать ... а так требование странное, учит программировать не правильно
34 PLUT
 
18.09.15
13:38
(32) через Объединить же, уже несколько раз написали выше
35 NcSteel
 
18.09.15
13:39
(34) Тут дебильное условие про вложенные.. за это надо экзаменатора на кол... в общем правильно что и не пошел к ним
36 senior
 
18.09.15
13:41
(33) чой то? а требование я так думаю, для проверки смекалки
37 GreatOne
 
18.09.15
13:43
(36) им видимо шашечки нужны.

Из последнего тестового задания было:
1) перевести на СКД валовую прибыль+добавить дополнительные поля остатков
2) перевести на СКД отчет продажи с добавлением полей остатка и себестоимости по выбранной валюте.

Вот это норм задания, есть смекалка или нет - не важно, главное чтобы работу работал.
38 GreatOne
 
18.09.15
13:45
+(37) для првоерки смекалки думаю надо перевести их справочник в РН и своять нормальный запрос. Код им предоставить
39 NcSteel
 
18.09.15
13:46
(38) +100500 )
40 eklmn
 
гуру
18.09.15
13:47
(30) +1
41 rchervak
 
18.09.15
13:47
Вот написал с ОБЪЕДЕНИТЬ:

в итоге получаю 4 строки вместо одной. как их можно сгруппирвоать? итоге не всчет


ВЫБРАТЬ
    ДвиженияТоваров.Номенклатура КАК Номенклатура,
    ДвиженияТоваров.Склад КАК Склад,
    СУММА(ВЫБОР
            КОГДА ДвиженияТоваров.дата <= &НачПериода
                ТОГДА ВЫБОР
                        КОГДА ДвиженияТоваров.ВидДвижения = ЗНАЧЕНИЕ(перечисление.ВидДвижения.приход)
                            ТОГДА ДвиженияТоваров.Количество
                        ИНАЧЕ -1 * ДвиженияТоваров.Количество
                    КОНЕЦ
            ИНАЧЕ 0
        КОНЕЦ) КАК НачальныйОстаток,
    0 КАК Приход,
    0 КАК Расход,
    0 КАК КонОстаок
ИЗ
    Справочник.ДвиженияТоваров КАК ДвиженияТоваров

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

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    ДвиженияТоваров.Номенклатура,
    ДвиженияТоваров.Склад,
    0,
    СУММА(ВЫБОР
            КОГДА ДвиженияТоваров.дата > &НачПериода
                    И ДвиженияТоваров.дата < &КонПериода
                ТОГДА ВЫБОР
                        КОГДА ДвиженияТоваров.ВидДвижения = ЗНАЧЕНИЕ(перечисление.ВидДвижения.приход)
                            ТОГДА ДвиженияТоваров.Количество
                        ИНАЧЕ 0
                    КОНЕЦ
            ИНАЧЕ 0
        КОНЕЦ),
    0,
    0
ИЗ
    Справочник.ДвиженияТоваров КАК ДвиженияТоваров

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

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    ДвиженияТоваров.Номенклатура,
    ДвиженияТоваров.Склад,
    0,
    0,
    СУММА(ВЫБОР
            КОГДА ДвиженияТоваров.дата > &НачПериода
                    И ДвиженияТоваров.дата < &КонПериода
                ТОГДА ВЫБОР
                        КОГДА ДвиженияТоваров.ВидДвижения = ЗНАЧЕНИЕ(перечисление.ВидДвижения.расход)
                            ТОГДА ДвиженияТоваров.Количество
                        ИНАЧЕ 0
                    КОНЕЦ
            ИНАЧЕ 0
        КОНЕЦ),
    0
ИЗ
    Справочник.ДвиженияТоваров КАК ДвиженияТоваров

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

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    ДвиженияТоваров.Номенклатура,
    ДвиженияТоваров.Склад,
    0,
    0,
    0,
    СУММА(ВЫБОР
            КОГДА ДвиженияТоваров.дата <= &КонПериода
                ТОГДА ВЫБОР
                        КОГДА ДвиженияТоваров.ВидДвижения = ЗНАЧЕНИЕ(перечисление.ВидДвижения.приход)
                            ТОГДА ДвиженияТоваров.Количество
                        ИНАЧЕ -1 * ДвиженияТоваров.Количество
                    КОНЕЦ
            ИНАЧЕ 0
        КОНЕЦ)
ИЗ
    Справочник.ДвиженияТоваров КАК ДвиженияТоваров

СГРУППИРОВАТЬ ПО
    ДвиженияТоваров.Номенклатура,
    ДвиженияТоваров.Склад
42 NcSteel
 
18.09.15
13:49
(41) Вложенный запрос.
Но твой запрос через объеденить тоже "не очень"...
43 rchervak
 
18.09.15
13:49
(42)вложеные незя
44 Бледно Золотистый
 
18.09.15
13:50
(37) Наверное шаблонистых кодеров у них и так достаточно, а нужен человек, решающий нестандартные задачи с "идиотскими" условиями.
45 NcSteel
 
18.09.15
13:51
(43) Так как и временные нельзя, то выгрузи в ТЗ и сверни в ТЗ ))))
46 Гёдза
 
18.09.15
13:52
(44) Случайно не задача с собеседования к PR?
47 rchervak
 
18.09.15
13:52
(45) задача на знание ЗАПРОСОВ
вытянуть запросом
48 Ненавижу 1С
 
гуру
18.09.15
13:52
это иммитация регистра накопления?
http://www.sql.ru/forum/622860/shablon-resursy-nakopleniya
49 rchervak
 
18.09.15
13:52
(46) не.
50 Гёдза
 
18.09.15
13:54
(49) Так она уже ведь решена в (0).
Более изящного вида этому г-ну уже не удастся придать
51 Ненавижу 1С
 
гуру
18.09.15
13:57
можно добавить условие:

ГДЕ
  ДвиженияТоваров.дата<=&КонПериода
52 ADirks
 
18.09.15
13:59
нормальный, типовой, запрос "остатки+движения" должен выглядеть так


ВЫБРАТЬ
    ДвиженияТоваров.Номенклатура,
    ДвиженияТоваров.Склад,
    Сумма(НачОст),
    Сумма(Приход),
    Сумма(Расход),
    (Сумма(НачОст) + Сумма(Приход) - Сумма(Расход)) КонОст
ИЗ
    (
    ВЫБРАТЬ
        ДвиженияТоваров.Номенклатура,
        ДвиженияТоваров.Склад,
        ВЫБОР
            КОГДА ДвиженияТоваров.ВидДвижения = ЗНАЧЕНИЕ(перечисление.ВидДвижения.приход) ТОГДА ДвиженияТоваров.Количество
            ИНАЧЕ -ДвиженияТоваров.Количество
        КОНЕЦ НачОст,
        0 Приход,
        0 Расход
    
    ИЗ
        Справочник.ДвиженияТоваров КАК ДвиженияТоваров
    ГДЕ
        ДвиженияТоваров.дата <= &НачПериода
        
    ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
        ДвиженияТоваров.Номенклатура,
        ДвиженияТоваров.Склад,
        0 НачОст,
        ВЫБОР
            КОГДА ДвиженияТоваров.ВидДвижения = ЗНАЧЕНИЕ(перечисление.ВидДвижения.приход) ТОГДА ДвиженияТоваров.Количество
            ИНАЧЕ 0
        КОНЕЦ Приход,
        ВЫБОР
            КОГДА ДвиженияТоваров.ВидДвижения = ЗНАЧЕНИЕ(перечисление.ВидДвижения.расход) ТОГДА ДвиженияТоваров.Количество
            ИНАЧЕ 0
        КОНЕЦ Расход
    
    ИЗ
        Справочник.ДвиженияТоваров КАК ДвиженияТоваров
    ГДЕ
        ДвиженияТоваров.дата > &НачПериода
        И ДвиженияТоваров.дата < &КонПериода
    ) ДвиженияТоваров
    
ГРУППИРОВАТЬ
        ДвиженияТоваров.Номенклатура,
        ДвиженияТоваров.Склад
53 rchervak
 
18.09.15
14:00
(52) это да.
54 Ненавижу 1С
 
гуру
18.09.15
14:02
(52) вот тут (Сумма(НачОст) + Сумма(Приход) - Сумма(Расход)) КонОст
можно словить NULL
55 rchervak
 
18.09.15
14:03
(54) проверку на NULL воткнуть и все
56 Гёдза
 
18.09.15
14:03
(54) Откуда?
57 Ненавижу 1С
 
гуру
18.09.15
14:04
одна из сумм может оказаться NULL, но (55) прав, я придераюсь
58 Гёдза
 
18.09.15
14:05
(57) не может
59 Маратыч
 
18.09.15
14:05
(57) Числовой реквизит не может быть NULL
60 ЧеловекДуши
 
18.09.15
14:06
(52) Вложенные нельзя, вы не сдали... :)

...
Я вообще предлагаю написать запрос на SQL... Как пишет 1С, тоже нельзя :)
61 Jonny_Khomich
 
18.09.15
14:11
(0) работа хорошая была?
62 rchervak
 
18.09.15
14:12
(61) не знаю. возможно. просто рядом с домом.
63 NcSteel
 
18.09.15
14:13
(50) Единственное что вижу это ЗНАЧЕНИЕ(перечисление.ВидДвижения.приход) заменить на параметры
64 Jonny_Khomich
 
18.09.15
14:13
(62) денег много обещали?
65 NcSteel
 
18.09.15
14:14
(52) Ужас, рукалицо
66 rchervak
 
18.09.15
14:15
(65) NcSteel по (41) можете помочь? или тут без вариантов?
67 NcSteel
 
18.09.15
14:16
(66) Уже написали что запросом не сгруппируешь , только вложенный запрос
68 NcSteel
 
18.09.15
14:16
(65) Расшифрую - Выбор когда в помойку, хотя конечно не так критично как в (41)
69 Ненавижу 1С
 
гуру
18.09.15
14:18
(58)(59) да, вы там явно прописали 0, согласен
70 gigi789
 
18.09.15
14:22
я может глупый но нельзя сделать реквизит справочника, типом ВидДвижеия.
71 rchervak
 
18.09.15
14:23
(70) можно "Перечсиление"
72 NcSteel
 
18.09.15
14:23
(70) Такого типа нет, есть системный тип ВидДвиженияНакопления, и ответ нет
73 ADirks
 
18.09.15
14:27
(68) если это условие перенести в WHERE, то будет 4 запроса вместо 2 и повторная выборка записей из таблички. А это не есть хорошо.
74 NcSteel
 
18.09.15
14:32
(73) КТо тебе сказал что будет повторная выборка?
75 NcSteel
 
18.09.15
14:32
(74) + ты думаешь оптимизатор запросов совсем глупенький?
76 mishgan75
 
18.09.15
14:34
Был такой анекдот, про то как мужику предложили бредовую историю, и в он как вариант сказал брошу пить, так и здесь - Уволить того кто придумал этот справочник для этой задачи. И никаких запросов не писать.
77 ADirks
 
18.09.15
14:40
(74) сервер сказал
вот такие вот два запроса выполняются с соотношением времени 66 / 34 %
и планы чётко показывают повторную выборку


select
    МПЗ,
    Sum(Количество)
from
(
select
    МПЗ,
    Количество
from
    регПартии
where
    Date_Time_IDDoc < '2012'
    and DebKred = 1
union all
select
    МПЗ,
    -Количество
from
    регПартии
where
    Date_Time_IDDoc < '2012'
    and DebKred = 2
) р
group by МПЗ




select
    МПЗ,
    Sum(Количество)
from
(
select
    МПЗ,
    CASE DebKred WHEN 1 THEN Количество ELSE -Количество END Количество
from
    регПартии
where
    Date_Time_IDDoc < '2012'
) р
group by МПЗ
78 Гёдза
 
18.09.15
14:42
вместо объединения можно полное соединение использовать
79 Гёдза
 
18.09.15
14:44
debkred - неселективное поле (всего 2 значения) поэтому всегда будет скан
80 ADirks
 
18.09.15
14:48
(79) Ну так то, если бы я эти таблички проектировал, то на каждый ресурс зафигачил бы 2 колонки, Приход и Расход. Но проектировал не я.
81 Aceforg
 
18.09.15
14:57
(41)  Надо было просто взять вместо справочника РН и задача просто решается с виртуальными таблицами остатков. А то что указано "Справочник Движение товаров", ну мало ли что указано, надо уметь переводить с языка юзверей.
82 Гёдза
 
18.09.15
15:00
(80) И чем это лучше? Разве CASE так много проца есть?
83 ADirks
 
18.09.15
15:03
(82) запросы красивше выглядели бы
84 NcSteel
 
18.09.15
15:14
(77) План ты не дал, давай план , посмотрим.