Имя: Пароль:
1C
1С v8
Запрос - задачка
, ,
0 AlStorm
 
09.10.12
11:56
Всем привет.
Столкнулся с такой задачей.
Есть рабочая конфигурация. В ней ведется учет продаж с нескольких складов. Нужно ДЛЯ КАЖДОГО склада вывести 3 таких дня, когда оборот (сумма продаж) были максимальные.
Вроде тривиально до ужаса, но я уже полчаса сижу и не могу построить запрос...
1 AlStorm
 
09.10.12
11:57
Я совсем тупой?
2 DrShad
 
09.10.12
11:58
(1) это провокация?
3 Wobland
 
09.10.12
11:58
на каждый день оборот можешь получить? упорядочить по сумме тоже можешь? взять первые три сумеешь?
4 DrShad
 
09.10.12
11:58
каким образом группировать периоды по три дня?
5 SUA
 
09.10.12
11:58
можно согласиться =)
6 AlStorm
 
09.10.12
12:01
(3)
Ты рассказываешь как получить первые 3 для одного склада, а если их 20?
Пример можешь показать?
7 Рэйв
 
09.10.12
12:01
(4)Да поодному сгруппируй, а потом отсортируПервый 3
8 Рэйв
 
09.10.12
12:01
*отсортируй по убыванию
9 AlStorm
 
09.10.12
12:02
(7)
Как? Не могу понять? Мне для кадого склада подзапрос рисовать?
Так в подзапросе к тому же нельзя упорядочивать
10 Рэйв
 
09.10.12
12:05
11 Rovan
 
гуру
09.10.12
12:07
(0) 3 подряд.... или любые 3 ?
12 AlStorm
 
09.10.12
12:07
(10)
Не врубаюсь нафиг мне это надо
13 AlStorm
 
09.10.12
12:07
(11)
3 максимальные для каждого склада.

То есть если складов 15, то вывод отчета должен быть длиной в 45 строк
14 Рэйв
 
09.10.12
12:08
(12)Ну уж если ты не врубаешься нафиг оно тебе, что про остальных то говорить:-)

Бросай все, езжай на Карибы
15 Симпатяшка
 
09.10.12
12:24
Я бы делала примерно так: Выбрать все обороты по всем складам на каждый день, упорядочить по сумме, сделать итоги по каждому складу. Обходить результат запроса по группировкам и во вложенном цикле выводить первые 3 строки, а потом этот цикл прерывать.
16 acsent
 
09.10.12
12:25
Задача из цикла срез последних руками
17 shuhard
 
09.10.12
12:32
(1)[Я совсем тупой?]
угу
18 Salimbek
 
09.10.12
12:33
или динамически строящийся запрос (по количеству складов) состоящий из подзапросов по очередному складу, объединенных через "Объединить все"
19 ptiz
 
09.10.12
12:42
Компоновка умеет выводить первые N записей
20 МихаилМ
 
09.10.12
12:44
это задача ранжирования
21 Pasha_mix
 
09.10.12
12:50
(17) Ты так заявлешь, буд-то у тебя есть решение.
22 Eugene_life
 
09.10.12
12:55
Запрос в цикле!!! По каждому складу находим максимум, исключаем, находим максимум, исключаем и т.п. Все выводим в табличку.
23 pavelul73
 
09.10.12
12:57
Выгрузить запрос в ТЗ, свернуть ТЗ по складам, отсортировать ТЗ по сумме, выбрать первые 3 значения.
24 ptiz
 
09.10.12
12:58
Короче, накатал от нечего делать

ВЫБРАТЬ
   ПродажиОбороты.Склад,
   ПродажиОбороты.СтоимостьОборот,
   ПродажиОбороты.Период
ПОМЕСТИТЬ ПродажиВсе
ИЗ
   РегистрНакопления.Продажи.Обороты(&Дата1, &Дата2, День, ) КАК ПродажиОбороты
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ПродажиВсе.Склад,
   МАКСИМУМ(ПродажиВсе.СтоимостьОборот) КАК СтоимостьОборот
ПОМЕСТИТЬ Максимум1День
ИЗ
   ПродажиВсе КАК ПродажиВсе

СГРУППИРОВАТЬ ПО
   ПродажиВсе.Склад
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ПродажиВсе.Склад,
   МАКСИМУМ(ПродажиВсе.СтоимостьОборот) КАК СтоимостьОборот
ПОМЕСТИТЬ Максимум2День
ИЗ
   ПродажиВсе КАК ПродажиВсе
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ Максимум1День КАК Максимум1День
       ПО (Максимум1День.Склад = ПродажиВсе.Склад)
           И (Максимум1День.СтоимостьОборот > ПродажиВсе.СтоимостьОборот)

СГРУППИРОВАТЬ ПО
   ПродажиВсе.Склад
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ПродажиВсе.Склад,
   МАКСИМУМ(ПродажиВсе.СтоимостьОборот) КАК СтоимостьОборот
ПОМЕСТИТЬ Максимум3День
ИЗ
   ПродажиВсе КАК ПродажиВсе
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ Максимум2День КАК Максимум2День
       ПО (Максимум2День.Склад = ПродажиВсе.Склад)
           И (Максимум2День.СтоимостьОборот > ПродажиВсе.СтоимостьОборот)

СГРУППИРОВАТЬ ПО
   ПродажиВсе.Склад
;

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

СГРУППИРОВАТЬ ПО
   Максимум1День.Склад,
   Максимум1День.СтоимостьОборот

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

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

СГРУППИРОВАТЬ ПО
   Максимум2День.Склад,
   Максимум2День.СтоимостьОборот

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

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

СГРУППИРОВАТЬ ПО
   Максимум3День.Склад,
   Максимум3День.СтоимостьОборот

УПОРЯДОЧИТЬ ПО
   Сумма УБЫВ
ИТОГИ ПО
   Склад
25 Fragster
 
гуру
09.10.12
13:06
вот, держите:


ВЫБРАТЬ
   "А" КАК Склад,
   1 КАК Период,
   3 КАК Сумма
ПОМЕСТИТЬ Данные

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

ВЫБРАТЬ
   "А",
   2,
   7

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

ВЫБРАТЬ
   "А",
   3,
   4

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

ВЫБРАТЬ
   "А",
   4,
   5

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

ВЫБРАТЬ
   "А",
   5,
   6
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   Данные.Склад,
   Данные.Период,
   Данные.Сумма
ПОМЕСТИТЬ ДанныеА
ИЗ
   Данные КАК Данные
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   Данные.Склад,
   Данные.Период,
   Данные.Сумма
ИЗ
   Данные КАК Данные
ГДЕ
   Данные.Период В
           (ВЫБРАТЬ ПЕРВЫЕ 2
               ДанныеА.Период
           ИЗ
               ДанныеА КАК ДанныеА
           ГДЕ
               ДанныеА.Склад = Данные.Склад
           УПОРЯДОЧИТЬ ПО
               ДанныеА.Сумма УБЫВ)
26 Fragster
 
гуру
09.10.12
13:07
единственное - передачу количества первых записей не сделать руками
27 Fragster
 
гуру
09.10.12
13:08
(26)+ вернее сделать, но это надо нумеровать таблицу по периодам в разрезе складов в порядке увеличения суммы, что долго
28 Fragster
 
гуру
09.10.12
13:09
ну и промежуточная таблица не нужна
29 ptiz
 
09.10.12
13:14
(25) Прикольно :)
С такиими условиями во вложенных запросах еще не работал
30 Симпатяшка
 
09.10.12
13:21
(22) Запрос в цикле - ай-яй-яй, зачем людей плохому учите?
31 Эльнур
 
09.10.12
13:51
Ну что получилось?
32 Fragster
 
гуру
09.10.12
13:52
(31) конечно, (25) же работает
33 Эльнур
 
09.10.12
13:56
Я вот такую вещь предлагаю, просто вместо склада - организация(для простоты). Можно и под склад переделать.

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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ПерваяПродажи.Организация,
   МАКСИМУМ(ПерваяПродажи.СтоимостьОборот) КАК СтоимостьОборот
ПОМЕСТИТЬ ПерваяВыборкаБезДат
ИЗ
   ПерваяПродажи КАК ПерваяПродажи

СГРУППИРОВАТЬ ПО
   ПерваяПродажи.Организация
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ПерваяПродажи.Организация,
   ПерваяПродажи.СтоимостьОборот
ПОМЕСТИТЬ ВтораяБезОбработки
ИЗ
   ПерваяПродажи КАК ПерваяПродажи
ГДЕ
   НЕ ПерваяПродажи.СтоимостьОборот В
               (ВЫБРАТЬ
                   ПерваяВыборкаБезДат.СтоимостьОборот
               ИЗ
                   ПерваяВыборкаБезДат КАК ПерваяВыборкаБезДат)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ВтораяБезОбработки.Организация,
   МАКСИМУМ(ВтораяБезОбработки.СтоимостьОборот) КАК СтоимостьОборот
ПОМЕСТИТЬ ВтораяВыборкаБезДат
ИЗ
   ВтораяБезОбработки КАК ВтораяБезОбработки

СГРУППИРОВАТЬ ПО
   ВтораяБезОбработки.Организация
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ПерваяВыборкаБезДат.Организация КАК Организация,
   ПерваяВыборкаБезДат.СтоимостьОборот
ПОМЕСТИТЬ ПерваяИВтораяБезДат
ИЗ
   ПерваяВыборкаБезДат КАК ПерваяВыборкаБезДат

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

ВЫБРАТЬ
   ВтораяВыборкаБезДат.Организация,
   ВтораяВыборкаБезДат.СтоимостьОборот
ИЗ
   ВтораяВыборкаБезДат КАК ВтораяВыборкаБезДат
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ПерваяПродажи.Организация,
   ПерваяПродажи.СтоимостьОборот
ПОМЕСТИТЬ ТретьяБезОбработки
ИЗ
   ПерваяПродажи КАК ПерваяПродажи
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ТретьяБезОбработки.Организация,
   МАКСИМУМ(ТретьяБезОбработки.СтоимостьОборот) КАК СтоимостьОборот
ПОМЕСТИТЬ ТретьяВыборкаБезДат
ИЗ
   ТретьяБезОбработки КАК ТретьяБезОбработки
ГДЕ
   НЕ ТретьяБезОбработки.СтоимостьОборот В
               (ВЫБРАТЬ
                   ПерваяИВтораяБезДат.СтоимостьОборот
               ИЗ
                   ПерваяИВтораяБезДат КАК ПерваяИВтораяБезДат)

СГРУППИРОВАТЬ ПО
   ТретьяБезОбработки.Организация
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ПерваяИВтораяБезДат.Организация КАК Организация,
   ПерваяИВтораяБезДат.СтоимостьОборот
ПОМЕСТИТЬ Предпоследняя
ИЗ
   ПерваяИВтораяБезДат КАК ПерваяИВтораяБезДат

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

ВЫБРАТЬ
   ТретьяВыборкаБезДат.Организация,
   ТретьяВыборкаБезДат.СтоимостьОборот
ИЗ
   ТретьяВыборкаБезДат КАК ТретьяВыборкаБезДат
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   Предпоследняя.Организация КАК Организация,
   Предпоследняя.СтоимостьОборот КАК СтоимостьОборот,
   ПерваяПродажи.Период
ИЗ
   ПерваяПродажи КАК ПерваяПродажи
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ Предпоследняя КАК Предпоследняя
       ПО ПерваяПродажи.Организация = Предпоследняя.Организация
           И ПерваяПродажи.СтоимостьОборот = Предпоследняя.СтоимостьОборот

УПОРЯДОЧИТЬ ПО
   Организация,
   СтоимостьОборот УБЫВ
</code>
34 Fragster
 
гуру
09.10.12
13:58
(33) жесть
35 AlStorm
 
09.10.12
14:00
Блин, и не ожидал такого нетривиального решения)
36 Эльнур
 
09.10.12
14:03
(35) мой вариант попробовал?
37 AlStorm
 
09.10.12
14:05
(36)
Да не, я уже дома.
Открыл мисту и офигел)
38 sergei123654
 
09.10.12
14:13
(0) Получить обороты по дням, отсортировать их по убыванию, потом ВЫБРАТЬ ПЕРВЫЕ 3

Иль не то?
39 AlStorm
 
09.10.12
14:20
(38)
ПО КАЖДОМУ СКЛАДУ
не то
40 n_egor
 
09.10.12
15:31
Предлагаю так. При данном подходе можно указать количество дат с максимальными продажами для каждого склада. Вместо суммы продаж использовано КоличествоРасход.

<code>
ВЫБРАТЬ
   ТоварыНаСкладахОбороты.КоличествоРасход,
   ТоварыНаСкладахОбороты.Период,
   ТоварыНаСкладахОбороты.Склад
ПОМЕСТИТЬ ВТОборотыНесортированные
ИЗ
   РегистрНакопления.ТоварыНаСкладах.Обороты(, , День, {(Номенклатура).* КАК Номенклатура}) КАК ТоварыНаСкладахОбороты
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ВТОборотыНесортированные1.Склад,
   ВТОборотыНесортированные1.КоличествоРасход,
   ВТОборотыНесортированные.Период
ПОМЕСТИТЬ ВТОборотыСоединение
ИЗ
   ВТОборотыНесортированные КАК ВТОборотыНесортированные
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТОборотыНесортированные КАК ВТОборотыНесортированные1
       ПО ВТОборотыНесортированные.Склад = ВТОборотыНесортированные1.Склад
           И ВТОборотыНесортированные.КоличествоРасход <= ВТОборотыНесортированные1.КоличествоРасход
;

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

СГРУППИРОВАТЬ ПО
   ВТОборотыСоединение.Склад,
   ВТОборотыСоединение.КоличествоРасход
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ВТОборотыСПорядкамиСумм.Склад,
   МАКСИМУМ(ВТОборотыСПорядкамиСумм.ПорядокСуммы) КАК ПорядокСуммы
ПОМЕСТИТЬ ВТОборотыСМаксимальнымПорядкомДляКаждогоСклада
ИЗ
   ВТОборотыСПорядкамиСумм КАК ВТОборотыСПорядкамиСумм

СГРУППИРОВАТЬ ПО
   ВТОборотыСПорядкамиСумм.Склад
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ВТОборотыСПорядкамиСумм.Склад,
   ВТОборотыСПорядкамиСумм.КоличествоРасход
ПОМЕСТИТЬ ВТОборотыНужныеСуммы
ИЗ
   ВТОборотыСПорядкамиСумм КАК ВТОборотыСПорядкамиСумм
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТОборотыСМаксимальнымПорядкомДляКаждогоСклада КАК ВТОборотыСМаксимальнымПорядкомДляКаждогоСклада
       ПО ВТОборотыСПорядкамиСумм.Склад = ВТОборотыСМаксимальнымПорядкомДляКаждогоСклада.Склад
ГДЕ
   ВТОборотыСМаксимальнымПорядкомДляКаждогоСклада.ПорядокСуммы - ВТОборотыСПорядкамиСумм.ПорядокСуммы < 3
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ВТОборотыНужныеСуммы.Склад,
   ВТОборотыНужныеСуммы.КоличествоРасход,
   ВТОборотыНесортированные.Период
ИЗ
   ВТОборотыНужныеСуммы КАК ВТОборотыНужныеСуммы
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТОборотыНесортированные КАК ВТОборотыНесортированные
       ПО ВТОборотыНужныеСуммы.Склад = ВТОборотыНесортированные.Склад
           И ВТОборотыНужныеСуммы.КоличествоРасход = ВТОборотыНесортированные.КоличествоРасход
</code>
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший