Имя: Пароль:
1C
1С v8
Совладать с левым соединением
0 AndrewM
 
02.07.12
19:17
Никак не могу сообразить, как избавиться от дублирования записей при левом соединении, когда больше одного элемента удовлетворяют условию соединения. В этом случае в результате запроса появляется несколько строк с одним и тем же элементом слева и разными элементами справа, удовлетворяющими одному условию.
Например, я хочу оставить только одну, последнюю, запись из подобных.
Как это можно сделать?
1 GROOVY
 
02.07.12
19:19
Сначала отобрать и сгруппировать источники, потом соединять.
2 йети
 
02.07.12
19:22
группировка по элементу слева и макс/мин по правому
3 AndrewM
 
02.07.12
20:47
(2) А если в запросе кроме этих 2-х полей я достаю другие, которые отличаются, как их сгруппировать?
4 NcSteel
 
02.07.12
20:52
Как определяется признак записи , что она последняя?
5 NcSteel
 
02.07.12
20:52
(4) + Если по дате, то делай два левых соединений.
6 AndrewM
 
02.07.12
20:56
(4) По дате и по числовому полю (приоритет на числовом поле, затем на дате). А два левых соединения - это как?
7 AndrewM
 
03.07.12
07:05
Вопрос ещё открыт. Запрос получился такой:

ВЫБРАТЬ
   РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК Дата,
   ДанныеДокументовУчета.Основание,
   ДанныеДокументовУчета.КТУ_АТУ,
   ДанныеДокументовУчета.КТУ_Заказ,
   ДанныеДокументовУчета.ЛистУчетаЭтоСтажер
ИЗ
   РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
       ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
           3 КАК Приоритет,
           ЛистУчетаРабочегоВремениТСОценкиУчастников.Ссылка КАК Основание,
           ЛистУчетаРабочегоВремениТСОценкиУчастников.Ссылка.ПутевойЛистОснование.ДатаНачФакт КАК ДатаНачала,
           ЛистУчетаРабочегоВремениТСОценкиУчастников.Ссылка.ПутевойЛистОснование.ДатаКонФакт КАК ДатаОкончания,
           ЛистУчетаРабочегоВремениТСОценкиУчастников.КТУату КАК КТУ_АТУ,
           ЛистУчетаРабочегоВремениТСОценкиУчастников.КТУзаказчика КАК КТУ_Заказ,
           ВЫБОР
               КОГДА ЛистУчетаРабочегоВремениТСОценкиУчастников.РольУчастника = "Стажер"
                   ТОГДА ИСТИНА
               ИНАЧЕ ЛОЖЬ
           КОНЕЦ КАК ЛистУчетаЭтоСтажер
       ИЗ
           Документ.ЛистУчетаРабочегоВремениТС.ОценкиУчастников КАК ЛистУчетаРабочегоВремениТСОценкиУчастников
       ГДЕ
           ЛистУчетаРабочегоВремениТСОценкиУчастников.Ссылка.Проведен = ИСТИНА
           И ЛистУчетаРабочегоВремениТСОценкиУчастников.Ссылка.ПутевойЛистОснование.Проведен = ИСТИНА
           И ЛистУчетаРабочегоВремениТСОценкиУчастников.Ссылка.ПутевойЛистОснование.Организация = &Организация
           И ЛистУчетаРабочегоВремениТСОценкиУчастников.Участник = &Водитель
           И (НАЧАЛОПЕРИОДА(ЛистУчетаРабочегоВремениТСОценкиУчастников.Ссылка.ПутевойЛистОснование.ДатаНачФакт, ДЕНЬ) МЕЖДУ &ДатаНач И &ДатаКон)
       
       ОБЪЕДИНИТЬ ВСЕ
       
       ВЫБРАТЬ
           1,
           РемонтныйЛистИсполнители.Ссылка,
           РемонтныйЛистИсполнители.ДатаНачала,
           РемонтныйЛистИсполнители.ДатаОкончания,
           РемонтныйЛистИсполнители.СИТ_КТУАТУ,
           0,
           "-"
       ИЗ
           Документ.РемонтныйЛист.Исполнители КАК РемонтныйЛистИсполнители
       ГДЕ
           РемонтныйЛистИсполнители.Ссылка.Проведен = ИСТИНА
           И РемонтныйЛистИсполнители.Ссылка.Организация = &Организация
           И РемонтныйЛистИсполнители.Сотрудник.Физлицо = &Водитель
           И (НАЧАЛОПЕРИОДА(РемонтныйЛистИсполнители.ДатаНачала, ДЕНЬ) МЕЖДУ &ДатаНач И &ДатаКон)
       
       ОБЪЕДИНИТЬ ВСЕ
       
       ВЫБРАТЬ
           2,
           ПутевойЛистПростои.Ссылка,
           ПутевойЛистПростои.ДатаПростоя,
           ПутевойЛистПростои.ДатаПростоя,
           ЛистУчетаРабочегоВремениТСОценкиУчастников.КТУату,
           0,
           "-"
       ИЗ
           Документ.ПутевойЛист.Простои КАК ПутевойЛистПростои
               ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
                   ЛистУчетаРабочегоВремениТСОценкиУчастников.Ссылка КАК Ссылка,
                   ЛистУчетаРабочегоВремениТСОценкиУчастников.КТУату КАК КТУату
               ИЗ
                   Документ.ЛистУчетаРабочегоВремениТС.ОценкиУчастников КАК ЛистУчетаРабочегоВремениТСОценкиУчастников
               ГДЕ
                   ЛистУчетаРабочегоВремениТСОценкиУчастников.Ссылка.Проведен = ИСТИНА) КАК ЛистУчетаРабочегоВремениТСОценкиУчастников
               ПО ПутевойЛистПростои.Ссылка = ЛистУчетаРабочегоВремениТСОценкиУчастников.Ссылка.ПутевойЛистОснование
       ГДЕ
           ПутевойЛистПростои.Ссылка.Проведен = ИСТИНА
           И ПутевойЛистПростои.ВремяПростоя >= 10
           И ПутевойЛистПростои.Ссылка.Организация = &Организация
           И (ПутевойЛистПростои.Ссылка.Водитель1 = &Водитель
                   ИЛИ ПутевойЛистПростои.Ссылка.Водитель2 = &Водитель
                   ИЛИ ПутевойЛистПростои.Ссылка.Стажер = &Водитель)
           И (НАЧАЛОПЕРИОДА(ПутевойЛистПростои.ДатаПростоя, ДЕНЬ) МЕЖДУ &ДатаНач И &ДатаКон)
       
       ОБЪЕДИНИТЬ ВСЕ
       
       ВЫБРАТЬ
           0,
           СостояниеРаботниковОрганизаций.Регистратор,
           СостояниеРаботниковОрганизаций.Период,
           СостояниеРаботниковОрганизаций.Период,
           "СреднееМесячноеЗначение",
           0,
           "-"
       ИЗ
           РегистрСведений.СостояниеРаботниковОрганизаций КАК СостояниеРаботниковОрганизаций
       ГДЕ
           НАЧАЛОПЕРИОДА(СостояниеРаботниковОрганизаций.Период, ДЕНЬ) МЕЖДУ &ДатаНач И &ДатаКон
           И СостояниеРаботниковОрганизаций.Сотрудник.Физлицо = &Водитель
           И СостояниеРаботниковОрганизаций.Организация = &Организация
           И СостояниеРаботниковОрганизаций.Состояние = &Состояние) КАК ДанныеДокументовУчета
       ПО (РегламентированныйПроизводственныйКалендарь.ДатаКалендаря МЕЖДУ НАЧАЛОПЕРИОДА(ДанныеДокументовУчета.ДатаНачала, ДЕНЬ) И НАЧАЛОПЕРИОДА(ДанныеДокументовУчета.ДатаОкончания, ДЕНЬ))
ГДЕ
   РегламентированныйПроизводственныйКалендарь.ДатаКалендаря МЕЖДУ &ДатаНач И &ДатаКон

УПОРЯДОЧИТЬ ПО
   Дата

Т.е. слева дни месяца, а справа относящиеся к ним документы. Задача в том, чтобы если на один и тот же день попадёт несколько документов, оставить только один (для этого есть поле "Приоритет").
8 DimVad
 
03.07.12
07:15
Как в (1). А для удобства то, что группируете - во временную таблицу.
9 AndrewM
 
03.07.12
07:26
(8) Источники я тоже не могу сгруппировать. Там же тоже кроме "Приоритета" есть поля, которые отличаются и не группируются.
А отобрать я представляю как с условиями в пределах одной записи. А как отобрать, сверяя разные записи? Т.е. есть запись с одной датой и с одним приоритетом (и ещё всякими полями) и есть вторая запись с той же датой и с уже другим приоритетом.
10 DimVad
 
03.07.12
07:33
(9) "Там же тоже кроме "Приоритета" есть поля, которые отличаются и не группируются. " - а что с ними нужно делать ? Если они участвуют в объединении, то дублей не будет. Если просто "любое значение" - функцией "макс". Если обрабатывать надо все значения - так и правильно, что дубли в запросе...
11 AndrewM
 
03.07.12
07:41
(10) Нужно выбрать максимальный приоритет за конкретный день, а остальные поля (не схожие) выбрать по этому приоритету. Ну т.е. как бы затереть поля с минимальным приоритетом полями с максимальным.
Короче, группировка нужна только по дате и приоритету, остальные поля должны быть выбраны исходя из даты и приоритета.
12 AndrewM
 
03.07.12
07:43
(10) + если смотреть по всем полям (а не только по дате и приоритету), то уже сейчас дублей нет.
13 AndrewM
 
03.07.12
07:45
(10) + может, я не верно выразился. Для меня это дубли, потому что мне надо, чтобы была одна запись с 3-м июля, а не несколько. А если смотреть по всем полям, то, как уже говорил, дублей нет, но меня это не устраивает.
14 kosts
 
03.07.12
08:05
15 AndrewM
 
03.07.12
10:00
Делаю, как в (1) и (4). Сначала группирую и отбираю в источнике, затем "склеиваю".

Возник вопрос: как получается группировка, если выбрать максимум по двум полям:

ВЫБРАТЬ
   НАЧАЛОПЕРИОДА(ДанныеДокументовУчета.ДатаНачала, ДЕНЬ) КАК ДатаНачала,
   МАКСИМУМ(ДанныеДокументовУчета.Приоритет) КАК Приоритет,
   МАКСИМУМ(ДанныеДокументовУчета.ДатаДокумента) КАК ДатаДокумента
ИЗ
   ...

Что я получаю в таком случае, не могу разобраться. Будет ли он искать сначала максимум по Приоритету, а затем, если найдётся два одинаковых приоритета, уже внутри дня и приоритета искать максимум по дате документа?
Или два максимума в одном "ВЫБРАТЬ ... ИЗ" не так работают?
16 hhhh
 
03.07.12
10:22
(15) тут надо за 2 этапа. Сначала ищешь максимум приоритета, помещаешь во временную таблицу, а потом делаешь внутреннее соединение с исходной таблицей - вытаскиваешь уже сами записи с этим приоритетом.
17 AndrewM
 
04.07.12
06:19
ok, так и сделал.

Первый запрос (для группировки по приоритетам):

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

Второй запрос (для группировки по приоритетам и дням):

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

И последний, контрольный:

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

Спасибо за наводку. :)