|
v7: Оптимизация запроса... | ☑ | ||
---|---|---|---|---|
0
bananan
04.02.13
✎
11:20
|
Есть такой код:
Процедура Сформировать(Пар) ТекстЗапроса = "//{{ЗАПРОС(СписокСотрудников) |Период с {ДатаАктуальности} по {ДатаАктуальности}; |Сотр = Справочник.Сотрудники.ТекущийЭлемент; |Фир = Справочник.Сотрудники.Фирма; |Оклад = Справочник.Сотрудники.Оклад; |КвоЛьгот = Справочник.Сотрудники.КвоЛьгот; |Тариф = Справочник.Сотрудники.Тариф; |Пенсионер = Справочник.Сотрудники.Пенсионер; |Инвалид = Справочник.Сотрудники.Инвалид; |Должность = Справочник.Сотрудники.МестоРаботы; |Ставка = Справочник.Сотрудники.Ставка; |Совместитель = Справочник.Сотрудники.ТипСотрудника; |ДатаПриема = Справочник.Сотрудники.ДатаПриема; |ДатаУвольнения = Справочник.Сотрудники.ДатаУвольнения; |Условие(Фир=Фирма); |Условие (Число(Сотр.Родитель.Код) <> 0); |Условие(Сотр в ВыбСотрудник); |Условие(ДатаПриема<>Дата(0)); |Условие(ДатаПриема<=ДатаАктуальности);"; Если фОсновные=0 Тогда ТекстЗапроса=ТекстЗапроса+" |Условие(Совместитель=1);"; КонецЕсли; Если фСовместители=0 Тогда ТекстЗапроса=ТекстЗапроса+" |Условие(Совместитель=0);"; КонецЕсли; Если Пар=1 Тогда ТекстЗапроса=ТекстЗапроса+" |Группировка Сотр Упорядочить По Сотр.Наименование;"; Иначе ТекстЗапроса=ТекстЗапроса+" |Группировка Сотр Упорядочить По Сотр.Код;"; КонецЕсли; ТекстЗапроса=ТекстЗапроса+" |Функция Окл = Сумма(Оклад); //|Функция Раб = Сумма(1) КОГДА ( (ДатаПриема<>Дата(0)) и (ДатаПриема<=ДатаАктуальности) и (ДатаЧисло(Запрос.ДатаУвольнения)<>0) и (Запрос.ДатаУвольнения<=ДатаАктуальности) ) ; |Функция Тар = Сумма(Тариф);"; Запрос = СоздатьОбъект("Запрос"); Если Запрос.Выполнить(ТекстЗапроса)=0 Тогда Возврат; КонецЕсли; Таб = СоздатьОбъект("Таблица"); Таб.ВывестиСекцию("Шапка|Основная"); Если фУволенные=1 Тогда Таб.ПрисоединитьСекцию("Шапка|Увольнение"); КонецЕсли; Если (фОсновные=1) и (фСовместители=1) Тогда Таб.ПрисоединитьСекцию("Шапка|Совместитель"); КонецЕсли; Кво = 0; Пока Запрос.Группировка("Сотр")=1 Цикл Состояние( "Обработка " + Запрос.Сотр); Если Запрос.Сотр.ЭтоГруппа() = 1 Тогда Запрос_=СоздатьОбъект("ODBCRecordset"); ТекстЗапроса = " |SELECT COUNT(*) as Кво |FROM $Справочник.Сотрудники Сотр |WHERE Сотр.ID IN (SELECT Val FROM #tmpSotr) |AND $Сотр.ДатаПриема> :Дат1 |AND $Сотр.ДатаПриема<= :ДатаАктуальности |AND ($Сотр.ДатаУвольнения = '01.01.1753' or $Сотр.ДатаУвольнения>= :ДатаАктуальности ) |"; Запрос_.УстановитьТекстовыйПараметр("Дат1", Дата("01.01.1989")); Запрос_.УстановитьТекстовыйПараметр("ДатаАктуальности", ДатаАктуальности+1); Запрос_.УложитьСписокОбъектов(Запрос.Сотр.ТекущийЭлемент(), "#tmpSotr","Сотрудники"); тЗанято = Запрос_.ВыполнитьСкалярный(ТекстЗапроса); ПоШтату = Запрос.Сотр.ПоШтату; ФиксДан = Шаблон("Занято: [тЗанято] \ По штату: [Запрос.Сотр.ПоШтату] \ Вакантно: [Запрос.Сотр.ПоШтату-тЗанято]"); Если фУволенные=0 Тогда Если тЗанято = 0 Тогда продолжить; Конецесли; Конецесли; Таб.ВывестиСекцию("Группа|Основная"); Если фУволенные=1 Тогда Таб.ПрисоединитьСекцию("Группа|Увольнение"); Конецесли; Если (фОсновные=1) и (фСовместители=1) Тогда Таб.ПрисоединитьСекцию("Группа|Совместитель"); КонецЕсли; Иначе Если (фУволенные=0) и (ДатаЧисло(Запрос.ДатаУвольнения)<>0) и (Запрос.ДатаУвольнения<=ДатаАктуальности) Тогда Продолжить; КонецЕсли; Кво = Кво + 1; //ОснПенс = ?(Запрос.Сотр.Пенсионер=1,"+",""); //ОснИнв = ?(Запрос.Сотр.Инвалид=1,"+",""); ОснПенс = ?(Запрос.Пенсионер=1,"+",""); ОснИнв = ?(Запрос.Инвалид=1,"+",""); Таб.ВывестиСекцию("Сотрудник|Основная"); Если фУволенные=1 Тогда Если (ДатаЧисло(Запрос.ДатаУвольнения)<>0) и (Запрос.ДатаУвольнения<=ДатаАктуальности) Тогда ДатаУвольнения = Формат(Запрос.ДатаУвольнения,"ДДММГГ"); Иначе ДатаУвольнения = ""; КонецЕсли; Таб.ПрисоединитьСекцию("Сотрудник|Увольнение"); КонецЕсли; Если (фОсновные=1) и (фСовместители=1) Тогда ОснСовм = ?(Запрос.Совместитель=1,"+",""); Таб.ПрисоединитьСекцию("Сотрудник|Совместитель"); КонецЕсли; КонецЕсли; КонецЦикла; Таб.ВывестиСекцию("Дно|Основная"); Если фУволенные=1 Тогда Таб.ПрисоединитьСекцию("Дно|Увольнение"); КонецЕсли; Если (фОсновные=1) и (фСовместители=1) Тогда Таб.ПрисоединитьСекцию("Дно|Совместитель"); КонецЕсли; Таб.Опции(0,0,0,0); Таб.ТолькоПросмотр(Константа.ФлагЗащитыТаблиц); Таб.Показать("Список сотрудников"); КонецПроцедуры Понято, что вызов запроса в цикле - не лучший вариант, если не скзать хуже... Так вот не могу сообразить как это сделать в одном запросе? В даном коде первый (верхний) запрос выбирает данные из справочника сотрудники, а второй (внутренний, тот что в цикле) - суммирует к-во ставок у сотрудников конкретного подразделения |
|||
1
Mikeware
04.02.13
✎
11:22
|
на третий круг?
|
|||
2
Aleksey
04.02.13
✎
11:23
|
(0) Работает, не трожь
|
|||
3
bananan
04.02.13
✎
11:27
|
(2) Работать - конечно же работает, но мягко говоря, некрасивый код у этого скрипта...
Как бы это сделать в одном запросе (стандартном либо 1С++)? |
|||
4
Mikeware
04.02.13
✎
11:28
|
(3) ты не поверишь...
нужно написать запрос, который выбирает все требуемые данные... |
|||
5
bananan
04.02.13
✎
11:30
|
(4) Верю. Но вот не пойму как это сделать...
Неделю был на больничном дома (ангина) и периодически в голове всплывал этот запрос, но так ничего нормального в голову не пришло... |
|||
6
viktor_vv
04.02.13
✎
11:34
|
(5) Ну заготовка у тебя есть, там где по группе, делай по всем, группу в отдельное поле выведи и без суммирования, результат засунь в индексированную таблицу, группировуй ее и воводи.
Вероятно буду проблемы с вложенными группами. Но в принципе при известном макисмальном уровен вложенности справочника можно. |
|||
7
chelentano
04.02.13
✎
11:35
|
(6) даже не пытайся что-то объяснять, тут сложный случай :)
(0) уменьшить свою з/п у руководства уже просил? |
|||
8
bananan
04.02.13
✎
11:38
|
(6) Как скрипт (и оба запросы) работает сейчас - прексрасно понимаю. Но вот как это сделать в одном запросе - голова не варит..
(6) по группе.. |Группировка Сотр Упорядочить По Сотр.Наименование;"; это имеется ввиду или как? |
|||
9
sapphire
04.02.13
✎
11:39
|
(1) Опять он :)
|
|||
10
bananan
04.02.13
✎
11:41
|
+(8) вся загвоздка в подразделении, если просто просуммировать к-во ставок у сотрудников - будет к-во ставок на фирме, а надо иметь количество ставок в каждом подразделении фирмы
|
|||
11
viktor_vv
04.02.13
✎
11:42
|
(8) Заготовка вот
Запрос_=СоздатьОбъект("ODBCRecordset"); ТекстЗапроса = " |SELECT COUNT(*) as Кво |FROM $Справочник.Сотрудники Сотр |WHERE Сотр.ID IN (SELECT Val FROM #tmpSotr) |AND $Сотр.ДатаПриема> :Дат1 |AND $Сотр.ДатаПриема<= :ДатаАктуальности |AND ($Сотр.ДатаУвольнения = '01.01.1753' or $Сотр.ДатаУвольнения>= :ДатаАктуальности ) |"; |
|||
12
bananan
04.02.13
✎
11:45
|
(11) C этой стороны я к задаче и не подходил... Попробую
|
|||
13
viktor_vv
04.02.13
✎
11:45
|
(11)+ Выкинь оттуда count добавь свои реквизиты, как в черном запросе и добавь поле родителя
|SELECT |Сотр.ParentID as [Родитель $Справочник.Сотрудники] |FROM $Справочник.Сотрудники Сотр и вперед. |
|||
14
chelentano
04.02.13
✎
11:46
|
(8) "голова не варит" - да поняли уже
|
|||
15
viktor_vv
04.02.13
✎
11:54
|
Хотя тебе проще выкинуть прямой запрос, и добавить функцию в твой обычный запрос и все.
|ДатаУвольнения = Справочник.Сотрудники.ДатаУвольнения; |Функция КолСотр = СчЁтчик(); |Условие(Фир=Фирма); |
|||
16
bananan
04.02.13
✎
11:54
|
(14) сообразительный ты
|
|||
17
bananan
04.02.13
✎
11:55
|
(15) что-то подобное мне в голову прихоидило, но как в функции считать к-во ставок в одном подраздеолении?
|
|||
18
viktor_vv
04.02.13
✎
11:57
|
(17) Не боись, на уровне
Пока Запрос.Группировка("Сотр")=1 Цикл Состояние( "Обработка " + Запрос.Сотр); Если Запрос.Сотр.ЭтоГруппа() = 1 Тогда КолСотр = Запрос.КолСотр ; оно само посчитается. |
|||
19
viktor_vv
04.02.13
✎
11:58
|
(18)+ Ты ж все равно в прямом считаешь только количество записей (сотрудников) попавших в условия выборки.
|
|||
20
bananan
04.02.13
✎
12:00
|
(18(19) это мне уже совсем понятно - сейчас так и попробую
|
|||
21
bananan
04.02.13
✎
12:07
|
Даже не вериться (как все просто) в цикле убрал прямой запрос и вызвал функцию - и ВСЕ.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |