Имя: Пароль:
1C
1С v8
Упорядочивание в запросе
, , ,
0 bahtik
 
17.03.14
21:42
Здравствуйте!
Скажите, если я выполнил запрос с определенным упорядочиванием, поместил результат во временную таблицу, а в другом запросе (использующим тот же менеджер временных таблиц) делаю выборку из этой временной таблицы без указания упорядочинвания, то записи в выборке будут располагаться в том порядке, в котором они были получены в первом запросе, или могут быть другие варианты?
1 Ненавижу 1С
 
гуру
17.03.14
21:44
вообще говоря, если используется ПОМЕСТИТЬ, то уже УПОРЯДОЧИТЬ нельзя
2 bahtik
 
17.03.14
21:51
(1) Можно Упорядочить ПО
3 H A D G E H O G s
 
17.03.14
21:52
ВЫБРАТЬ ПЕРВЫЕ 9999999
4 bahtik
 
17.03.14
21:52
(1) С этим у меня проблем нет, временная таблица упорядочивается, как мне нужно.
5 bahtik
 
17.03.14
21:56
В общем, вопрос в том, нужно ли во втором запросе делать упорядочинвание или это не обязательно?
6 bahtik
 
17.03.14
21:56
(3) ?
7 H A D G E H O G s
 
17.03.14
21:59
(6) (3) к (1).

Как можно упорядочивать при помещении в ВТ
8 bahtik
 
17.03.14
21:59
(1) Аааа, да, ступил. Я потом добавил ВТ и запрос перестал работать. Так что, действительно, нельзя. Сорри.
9 bahtik
 
17.03.14
22:00
(7) Да, уже понял, вопрос снят.
10 bahtik
 
17.03.14
22:02
(7) Выходит, что нелишним будет построить индексы в ВТ и уже во втором запросе делать упорядочивание?
11 H A D G E H O G s
 
17.03.14
22:28
(10) зачем индексы в вт?
12 bahtik
 
17.03.14
22:33
(11) Чтоб потом делать выборку с упорядочиванием по индексированным полям.
13 bahtik
 
17.03.14
22:34
(12) Чтоб ускорить выполнение запроса.
14 H A D G E H O G s
 
17.03.14
22:34
(13) Ты его не ускоришь
15 bahtik
 
17.03.14
22:37
(14) Почему?
16 bahtik
 
17.03.14
22:37
(14) Индексы вроде для этого и нужны ведь?
17 H A D G E H O G s
 
17.03.14
22:38
(16) Ты дольше Индексы строить будешь, чем Упорядочивать.
18 bahtik
 
17.03.14
22:39
(17) Понятно. Тогда в каких случаях их целесообразно строить?
19 H A D G E H O G s
 
17.03.14
22:39
(16) Индексы нужны там, где много раз Читается, а не 1 раз.

В 95% случаев во Временных таблицах Индексы не нужны.
20 bahtik
 
17.03.14
22:39
(19) Ясно. Понял, что нужно почитать про индексы )) Спасибо за ответ.
21 bahtik
 
17.03.14
22:40
(19) Хотя, стоп! А у меня как раз много раз читается
22 H A D G E H O G s
 
17.03.14
22:41
(21) Покажи.
23 bahtik
 
17.03.14
22:42
Это запрос для получения таблицы для списания партий ТМЦ. Сначала я получаю общую таблицу, где есть нужные мне остатки (ну, с отбором по таб. части, конечно). А потом по каждой строке делаю отдельный запрос к первому и списываю партии.
Ща выложу.
24 bahtik
 
17.03.14
22:43
Запрос = Новый Запрос;
    Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
    Запрос.Текст =
        "ВЫБРАТЬ
        |    ОприходованиеТМЦПереченьТМЦ.ТМЦ,
        |    ОприходованиеТМЦПереченьТМЦ.ВариантТМЦ,
        |    ОприходованиеТМЦПереченьТМЦ.Партия,
        |    СУММА(ОприходованиеТМЦПереченьТМЦ.Количество * ОприходованиеТМЦПереченьТМЦ.Коэффициент) КАК КоличествоВБазЕд
        |ПОМЕСТИТЬ ПереченьТМЦ
        |ИЗ
        |    Документ.ОприходованиеТМЦ.ПереченьТМЦ КАК ОприходованиеТМЦПереченьТМЦ
        |ГДЕ
        |    ОприходованиеТМЦПереченьТМЦ.Ссылка = &Ссылка
        |
        |СГРУППИРОВАТЬ ПО
        |    ОприходованиеТМЦПереченьТМЦ.ВариантТМЦ,
        |    ОприходованиеТМЦПереченьТМЦ.Партия,
        |    ОприходованиеТМЦПереченьТМЦ.ТМЦ
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |    НеоприходованныеЗакупленныеТМЦОстатки.ТМЦ КАК ТМЦ,
        |    НеоприходованныеЗакупленныеТМЦОстатки.ВариантТМЦ КАК ВариантТМЦ,
        |    НеоприходованныеЗакупленныеТМЦОстатки.Партия КАК Партия,
        |    НеоприходованныеЗакупленныеТМЦОстатки.КоличествоОстаток,
        |    НеоприходованныеЗакупленныеТМЦОстатки.СтоимостьОстаток
        |ПОМЕСТИТЬ НеоприходованныеТМЦ
        |ИЗ
        |    РегистрНакопления.НеоприходованныеЗакупленныеТМЦ.Остатки(
        |            &ТочкаИтогов,
        |            Организация = &Организация
        |                И МОЛ = &МОЛ
        |                И СкладНазначения = &Склад
        |                И (&ПартионныйУчет
        |                        И (ТМЦ, ВариантТМЦ, Партия) В
        |                            (ВЫБРАТЬ
        |                                ПереченьТМЦ.ТМЦ,
        |                                ПереченьТМЦ.ВариантТМЦ,
        |                                ПереченьТМЦ.Партия
        |                            ИЗ
        |                                ПереченьТМЦ КАК ПереченьТМЦ)
        |                    ИЛИ НЕ &ПартионныйУчет
        |                        И (ТМЦ, ВариантТМЦ) В
        |                            (ВЫБРАТЬ
        |                                ПереченьТМЦ.ТМЦ,
        |                                ПереченьТМЦ.ВариантТМЦ
        |                            ИЗ
        |                                ПереченьТМЦ КАК ПереченьТМЦ))) КАК НеоприходованныеЗакупленныеТМЦОстатки
        |
        |ИНДЕКСИРОВАТЬ ПО
        |    ТМЦ,
        |    ВариантТМЦ,
        |    Партия
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |    ПереченьТМЦ.ТМЦ,
        |    ПереченьТМЦ.ВариантТМЦ,
        |    ПереченьТМЦ.Партия,
        |    ПереченьТМЦ.КоличествоВБазЕд
        |ИЗ
        |    ПереченьТМЦ КАК ПереченьТМЦ";
    
    Запрос.УстановитьПараметр("Ссылка", Ссылка);
    Запрос.УстановитьПараметр("ТочкаИтогов", Новый Граница(Ссылка.МоментВремени(), ВидГраницы.Исключая));
    Запрос.УстановитьПараметр("Организация", Организация);
    Запрос.УстановитьПараметр("МОЛ", МОЛ);
    Запрос.УстановитьПараметр("Склад", Склад);
    Запрос.УстановитьПараметр("ПартионныйУчет", СпособОценкиМПЗ = Перечисления.СпособыОценкиМПЗ.ПоПартиям);
    
    ПакетРезультатов = Запрос.ВыполнитьПакет();
    ВыборкаПоОстаткам = ПакетРезультатов[1];
    ПереченьТМЦвДокументе = ПакетРезультатов[2].Выгрузить();
    
    Для Каждого СтрокаПеречняТМЦ из ПереченьТМЦвДокументе Цикл
        ТМЦ = СтрокаПеречняТМЦ.ТМЦ;
        ВариантТМЦ = СтрокаПеречняТМЦ.ВариантТМЦ;
        Партия = СтрокаПеречняТМЦ.Партия;
        
        Запрос.Текст =
            "ВЫБРАТЬ
            |    НеоприходованныеТМЦ.ТМЦ КАК ТМЦ,
            |    НеоприходованныеТМЦ.ВариантТМЦ КАК ВариантТМЦ,
            |    НеоприходованныеТМЦ.Партия КАК Партия,
            |    НеоприходованныеТМЦ.КоличествоОстаток КАК КоличествоОстаток,
            |    НеоприходованныеТМЦ.СтоимостьОстаток
            |ИЗ
            |    НеоприходованныеТМЦ КАК НеоприходованныеТМЦ
            |ГДЕ
            |    НеоприходованныеТМЦ.ТМЦ = &ТМЦ
            |    И НеоприходованныеТМЦ.ВариантТМЦ = &ВариантТМЦ
            |    И (НеоприходованныеТМЦ.Партия = &Партия
            |            ИЛИ НЕ &ПартионныйУчет)
            |
            |УПОРЯДОЧИТЬ ПО
            |    ТМЦ,
            |    ВариантТМЦ,
            |    Партия
            |ИТОГИ
            |    СУММА(КоличествоОстаток)
            |ПО
            |    ОБЩИЕ
            |АВТОУПОРЯДОЧИВАНИЕ";
25 SSSSS_AAAAA
 
17.03.14
22:44
Упорядочивание(сортировка) имеет смысл только в самом последнем запросе. Никакие сортировки в промежуточных результатах никак не повлияют на выполнение запросов кроме замедления этого самого выполнения ибо сортировка одна из самых дорогих операций. Не повлияют они и на правильность результата потому, что при выполнении запросов эти сортировки никак и ничем не учитывается.
26 bahtik
 
17.03.14
22:45
(25) Спасибо, это я уже понял. Вот, сделал в последнем запросе сортировку. Теперь вопрос, нужны ли индексы.
27 H A D G E H O G s
 
17.03.14
22:46
(25) Учитываются.

У ВТ нет кластерного индекса, как в нее поместишь, так она и выберет.
28 H A D G E H O G s
 
17.03.14
22:46
(26) Запрос бредовый.
29 bahtik
 
17.03.14
22:46
(28) Что не так?
30 H A D G E H O G s
 
17.03.14
22:47
(25) Естественно, я не говорю про indexscan по какому-то созданному индексу. Но к этому не стоит приходить.
31 bahtik
 
17.03.14
22:49
Задача тривиальная - нужно списать количество и себестоимость остатков партий по ФИФО (например).
32 H A D G E H O G s
 
17.03.14
22:49
(29)

1) Запрос в цикле.
2)
кусок

  И МОЛ = &МОЛ
        |                И СкладНазначения = &Склад
        |                И (&ПартионныйУчет
        |                        И (ТМЦ, ВариантТМЦ, Партия) В
        |                            (ВЫБРАТЬ
        |                                ПереченьТМЦ.ТМЦ,
        |                                ПереченьТМЦ.ВариантТМЦ,
        |                                ПереченьТМЦ.Партия
        |                            ИЗ
        |                                ПереченьТМЦ КАК ПереченьТМЦ)
        |                    ИЛИ НЕ &ПартионныйУчет
        |                        И (ТМЦ, ВариантТМЦ) В
        |                            (ВЫБРАТЬ
        |                                ПереченьТМЦ.ТМЦ,
        |                                ПереченьТМЦ.ВариантТМЦ
        |                            ИЗ
        |                                ПереченьТМЦ КАК ПереченьТМЦ)))


сломал мой мозг.

Транслятор 1С и оптимизатор планов запросов sql тебе похлопают за него по плечу, вот как эти 2 парня

http://cs424418.vk.me/v424418879/4545/hbvzbHbE3N4.jpg


Открываем методичку 1С, смотрим как партии списываются.
33 bahtik
 
17.03.14
22:54
(32) Методички, к сожалению нет.
По первому пункту - возможны два варианта - либо запрос в цикле, либо выгрузка результата в таблицу значений и потом Таб.НайтиСтроки(Отбор). Второй вариант предпочтительнее?
По второму - ну да, немного запутанно, но суть в том, что либо сравниваем по трем полям (ТМЦ, вариант и партия), либо только по двум (ТМЦ, вариант) - в зависимости от того, ведется ли партионный учет вручную.
34 bahtik
 
17.03.14
22:55
(32) А какой общий принцип списания партий в той самой методичке?
35 bahtik
 
17.03.14
22:55
(34) ...чтоб я велосипед не изобретал.
36 H A D G E H O G s
 
17.03.14
22:56
вот что происходит, когда не здаешь специалиста
37 bahtik
 
17.03.14
22:59
Так я и не специалист )) Учусь еще.
38 bahtik
 
17.03.14
23:00
Ну в общих чертах какой алгоритм?
39 bahtik
 
17.03.14
23:00
В семерочных типовых было примерно так, как я сделал. Только еще хуже. ))
40 erp20
 
17.03.14
23:06
(10) http://kb.1c.ru/articleView.jsp?id=44#subquery_join, следуйте простым рекомендациям из этой статьи. В большинстве случаев они будут полезны и эффективны. В остальных случаях, нужно будет уже плотно СУБД изучать.
41 H A D G E H O G s
 
17.03.14
23:10
(37)

В общих чертах я бы сделал так

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


Ну а дальше - смотря что надо:
1) Сказать, что остатка в целом не хватает и отменить - Обходим Общие итоги (надо добавить в запрос).
2) Сказать, что остатка не хватает по конкретным номенклатурам и отменить - обходим вначале Итоги по номенклатуре, потом, если все хорошо - по номенклатуре и детальным.
3) Сказать, что остатка не хватает по конкретным номенклатурам и списать что есть - обходим Итоги по номенклатуре и по детальным записям.
42 H A D G E H O G s
 
17.03.14
23:10
У меня - fifo
43 bahtik
 
17.03.14
23:15
(42) Ага, ну принцип у меня примерно тот же самый, только вместо третьего запроса в пакете я делаю тот самый нехороший запрос в цикле...
44 bahtik
 
17.03.14
23:16
...а тут левое соединение и обход по группировкам...
45 H A D G E H O G s
 
17.03.14
23:16
А еще лучше - я бы Табличную часть документа передал бы через ТЗ, выгруженную по нужным колонкам, а Номенклатуру в параметр ВТ передал бы Свернутым массивом, выгруженным из колонки "Номенклатура", чтобы не рисковать с конструкцией EXIST, которая у меня не попадала в Индекс.
46 bahtik
 
17.03.14
23:18
(45) Ну вначале я ТЗ так и передавал (выгружал нужные колонки, сворачивал с пересчетом в базовые единицы измерения и т.п.) Но потом подглядел в сети такой вариант и переделал так.
47 bahtik
 
17.03.14
23:19
(45) А номенклатуру свернутым массивом не получится: у меня Номенклатура+Вариант
48 bahtik
 
17.03.14
23:19
...а если включен ручной учет партий, то получается, что Номенклатура+Вариант+Партия
49 bahtik
 
17.03.14
23:21
... поэтому у меня вместо свернутого массива свернутая ТЗ
50 bahtik
 
17.03.14
23:24
(40) Спасибо за ссылку, полезная информация.
51 bahtik
 
17.03.14
23:27
(45) Кстати, к вопросу об индексах. Вот из этой статьи в (40):
Внимание! Не забудьте проиндексировать созданную временную таблицу. В качестве индексных полей следует указать все поля, которые используются в условии соединения.
52 H A D G E H O G s
 
18.03.14
00:41
(51) Я несогласен с ними.