Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
22 ноя 2024, 15:46

Запрос без повторений строк

Автор Dezmont89, 24 июн 2015, 13:25

0 Пользователей и 1 гость просматривают эту тему.

Dezmont89

Нужно составить запрос к примеру у Человека есть Договор(номер,дата,срок, сумма)
к примеру  1 таблица людей
Ваня,Петя,Катя
2 таб договоров
У Вани №1 02.12.2005 12  1005, №2 02.12.2005 12  1000, №3 03.12.2005 12  1005
У Пети №4 02.12.2005 12  1015
У кати нет

В результат надо вывести нужно вывести один договор у человека с максимальной суммой, если таких несколько максимальной датой

Ваня №3
Петя №4
Катя NULL

Вот че то у меня какой то бред выходит:dfbsdfbsdf:

vitasw

Сразу оговорюсь, запрос намеренно составлен не совсем оптимально, для лучшего понимания
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.Ссылка КАК Контрагент
|ПОМЕСТИТЬ втКонтрагент
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| СчетНаОплатуПокупателю.Контрагент,
| СчетНаОплатуПокупателю.Дата,
| СчетНаОплатуПокупателю.СуммаДокумента,
| СчетНаОплатуПокупателю.Ссылка КАК Договор
|ПОМЕСТИТЬ втДоговоры
|ИЗ
| Документ.СчетНаОплатуПокупателю КАК СчетНаОплатуПокупателю
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| втКонтрагент.Контрагент,
| втДоговоры.Дата,
| втДоговоры.СуммаДокумента,
| втДоговоры.Договор
|ПОМЕСТИТЬ втОбщая
|ИЗ
| втКонтрагент КАК втКонтрагент
| ЛЕВОЕ СОЕДИНЕНИЕ втДоговоры КАК втДоговоры
| ПО втКонтрагент.Контрагент = втДоговоры.Контрагент
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| втОбщая.Контрагент,
| втОбщая.Договор
|ИЗ
| втОбщая КАК втОбщая
| ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| втОбщая.Контрагент КАК Контрагент,
| МАКСИМУМ(втОбщая.Дата) КАК Дата,
| втОбщая.СуммаДокумента КАК СуммаДокумента
| ИЗ
| втОбщая КАК втОбщая
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| втОбщая.Контрагент КАК Контрагент,
| МАКСИМУМ(втОбщая.СуммаДокумента) КАК СуммаДокумента
| ИЗ
| втОбщая КАК втОбщая
|
| СГРУППИРОВАТЬ ПО
| втОбщая.Контрагент) КАК ВложенныйЗапрос
| ПО втОбщая.Контрагент = ВложенныйЗапрос.Контрагент
| И втОбщая.СуммаДокумента = ВложенныйЗапрос.СуммаДокумента
|
| СГРУППИРОВАТЬ ПО
| втОбщая.Контрагент,
| втОбщая.СуммаДокумента) КАК ВложенныйЗапрос
| ПО втОбщая.Контрагент = ВложенныйЗапрос.Контрагент
| И втОбщая.СуммаДокумента = ВложенныйЗапрос.СуммаДокумента
| И втОбщая.Дата = ВложенныйЗапрос.Дата";

Результат = Запрос.Выполнить();

Dezmont89

Цитата: vitasw от 24 июн 2015, 13:46
Сразу оговорюсь, запрос намеренно составлен не совсем оптимально, для лучшего понимания



Спасибо делал почти так же но без временных таблиц. Просто подзапросами, поэтому наверное и запутался, не так удобно.
А как его можно оптимизировать?

vitasw

втОбщие - можно получить одним простым запросом по левому соединению.

LexaK

классика,
используются две временных таблицы,

но есть вопрос,  какой вы ожидаете результат, если будет несколько одинаковых(максимальных) сумм, по контрагентам, и несколько договоров на одинаковую дату, по этим суммам?
у вас произойдет мультиплицирование (задвоение) строк,

скорее всего второе условие не по дате договора надо делать а по его номеру( в пределах года, где соблюдается уникальность номеров), при условии уникальности номеров, или по паре дате и номер.

еще в вашем запросе нет отбора/условий по параметрам,
в больших базах сотни контрагентов, и десятки тысяч документов, и обычно интересуют данные за какой-то период, и естественно только от проведенных документов,
отсюда плавно переходим к пониманию что данный запрос надо строить на регистре(ах) по правильному если программировать.



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

    Результат = Запрос.Выполнить();
если помогло нажмите: Спасибо!

Dezmont89

Спасибо.
Ну я как то так и сделал. Чуть по своему.
Конечно у меня есть отборы, и по контрагентам до отбора по договорам, и по самим договорам. И запрос по регистрам.
И один человек по сути не может заключить два договора, в одно и тоже время с точностью до секунды.
Могу скинуть в личку весь текст запроса, может научите уму-разуму.

Похожие темы (5)

Рейтинг@Mail.ru

Поиск