Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Обычная тема Мой первый прямой запрос SQL (число прочтений - 2426 )
Darlok
YaBB Newbies
*
Отсутствует


Знание - сила!

Сообщений: 8
Местоположение: Новосибирск
Зарегистрирован: 18. Сентября 2007
Пол: Мужской
Мой первый прямой запрос SQL
18. Сентября 2007 :: 11:07
Печать  
Буду примного благодарен услышать критику по отчету который я написал.

Функция ПолучитьЗапросомСКЛ(НачДата,КонДата)

     ВремяНачалаЗамера=_GetPerformanceCounter();
     
     ТекстЗапроса = "   
     |   
//      Составим результирующую таблицу
     |      Select   
     |   
     |            $СпрНоменклатур.Группы as [Группа $Справочник.Группы],
     |            Результат.Товар as [Товар $Справочник.ДляМагазинов],
     |            Sum(КолВоТочек) as КолВоТочек,
     |         Sum(Продажи) as Продажи,
     |            Sum(ПродажиВРуб) as ПродажиВРуб,
     |            Sum(Доход) as Доход
     |   
     |      From 
     |      ( 
     |   
//      Составим промежуточную таблицу, для подсчета точек продаж
     |            Select   
     |   
     |                  Клиент as Клиент,
     |                  Товар as Товар,
     |                  1 as КолВоТочек,
     |                  Sum(АВотИНашиПродажи) as Продажи,
     |                  Sum(АВотИНашиПродажи * ЦенаПродаж) as ПродажиВРуб,
     |                  (Sum(АВотИНашиПродажи * ЦенаПродаж) - Sum(АВотИНашиПродажи * ЦенаПриходов)) as Доход
     |
     |            From 
     |            ( 
     |   
//      Составим таблицу с данными о движениях регистов
     |                  Select   
     |
     |                        tmp.Клиент as Клиент,
     |                        tmp.Товар as Товар,
     |                        tmp.ГодИздания as ГодИздания,
     |                        tmp.НомерИздания as НомерИздания,
     |                        tmp.ЦенаПродаж as ЦенаПродаж,
//      Считаем продажи по формулам в зависимости от условий
     |                        Sum(
     |                              Case
     |                                    When
     |                                          ВозПост.ТоварВ is Null
     |                                    Then
     |                                          tmp.КолВоИнвРасход - tmp.КолВоИнвПриход
     |                                    Else
     |                                          tmp.КолВоНачОст + tmp.КолВоПриход - tmp.КолВоРасход
     |                              End) as АВотИНашиПродажи,
//      Выбираем значения цен приходов, из регистра "Цены Приходов", либо из справочника если нет в регистре
     |                        Max(
     |                              Case
     |                                    When
     |                                          ПриходЦены.ТоварП is Null or ПриходЦены.ЦенаПриходов = 0
     |                                    Then
     |                                          $СпрНоменклатур.ВхЦена
     |                                    Else
     |                                          ПриходЦены.ЦенаПриходов
     |                              End) as ЦенаПриходов
     |
     |                  From
     |                  (
     |   
//      Выбираем начальные остатки из таблицы промежуточных итогов остаточного регистра на начало месяца от выбранной даты начала
     |                        Select
     |                              $reg.Клиент as Клиент,
     |                              $reg.Товар as Товар,
     |                              $reg.ГодИздания as ГодИздания,
     |                              $reg.НомерИздания as НомерИздания,
     |                              $reg.Цена as ЦенаПродаж,
     |                              $reg.КолВо as КолВоНачОст,
     |                              0 as КолВоПриход,
     |                              0 as КолВоРасход,
     |                              0 as КолВоИнвРасход,
     |                              0 as КолВоИнвПриход
     |                        From      
     |                            $РегистрИтоги.ОстаткиНаМагазинах as reg (NOLOCK) 
     |                        Where 
     |                              (PERIOD = {d :ДатаОстатков})
     |
     |                        Union All 
     |
//      Выберем обороты за период от даты итогов до даты начала периода, тем самым получим начальные остатки по регистру на дату начала
     |                        Select
     |                              $reg.Клиент as Клиент,
     |                              $reg.Товар as Товар,
     |                              $reg.ГодИздания as ГодИздания,
     |                              $reg.НомерИздания as НомерИздания,
     |                              $reg.Цена as ЦенаПродаж,
     |                              (1 - reg.DEBKRED * 2)*$reg.КолВо as КолВоНачОст,
     |                              0 as КолВоПриход,
     |                              0 as КолВоРасход,
     |                              0 as КолВоИнвРасход,
     |                              0 as КолВоИнвПриход
     |                        From
     |                              $Регистр.ОстаткиНаМагазинах as reg (NOLOCK) 
     |                        Where
     |                           (DATE_TIME_IDDOC>=:ДатаНачОстатков and   DATE_TIME_IDDOC<:датН)
     |
     |                        Union All 
     |
//      Выбираем обороты из таблицы за период от выбранных даты начала до даты конца
     |                        Select   
     |                              $reg.Клиент as Клиент,
     |                              $reg.Товар as Товар,
     |                              $reg.ГодИздания as ГодИздания,
     |                              $reg.НомерИздания as НомерИздания,
     |                              $reg.Цена as ЦенаПродаж,
     |                              0 as КолВоНачОст,
//      Считаем приходы по виду документа
     |                              Case
     |                                    When
     |                                          (reg.DEBKRED = 0) and (jrn.idDocDef = $ВидДокумента.ВедомостьМагазинов)
     |                                    Then
     |                                          $reg.КолВо
     |                                    Else
     |                                          0
     |                              End as КолВоПриход,
//      Считаем расходы по виду документа
     |                              Case
     |                                    When
     |                                          (reg.DEBKRED = 1) and (jrn.idDocDef = $ВидДокумента.ВозвратОтМагазинов)
     |                                    Then
     |                                          $reg.КолВо
     |                                    Else
     |                                          0
     |                              End as КолВоРасход,
//      Считаем приходы по инвентаризации
     |                              Case
     |                                    When
     |                                          (reg.DEBKRED = 1) and (jrn.idDocDef = $ВидДокумента.ИнвентаризацияМагазина)
     |                                    Then
     |                                          $reg.КолВо
     |                                    Else
     |                                          0
     |                              End as КолВоИнвРасход,
//      Считаем расходы по инвентаризации
     |                              Case
     |                                    When
     |                                          (reg.DEBKRED = 0) and (jrn.idDocDef = $ВидДокумента.ИнвентаризацияМагазина)
     |                                    Then
     |                                          $reg.КолВо
     |                                    Else
     |                                          0
     |                              End as КолВоИнвПриход
     |            
     |                        From
     |                                  $Регистр.ОстаткиНаМагазинах as reg (NOLOCK) 
     |
//      Присоединим таблицу "журнал", нужна для определения вида документов
     |                        left outer join
     |                              _1SJourn jrn (nolock) ON jrn.iddoc = reg.iddoc 
     |
     |                        Where 
     |                              (reg.DATE_TIME_IDDOC>=:датН and  reg.DATE_TIME_IDDOC<:датК~)
     |
     |                  ) as tmp
     |
//      Присоединим колонку для определения было это издание в возврате поставщику или нет
     |                  Left outer Join
     |                        (
     |                              Select distinct
     |                                    $РегВозПост.Товар as ТоварВ,
     |                                    $РегВозПост.ГодИздания as ГодИзданияВ,
     |                                    $РегВозПост.НомерИздания as НомерИзданияВ
     |                              From
     |                                    $Регистр.ВозвратПост as РегВозПост (NOLOCK) 
//      Присоединим документ возврат списание, для опредения вида списания указанного в реквизите документа
     |                              Inner join
     |                                    $Документ.ВозвратСписание ДокВозврСпис (nolock) ON ДокВозврСпис.iddoc = РегВозПост.iddoc 
     |                              Where 
     |                                    (РегВозПост.DATE_TIME_IDDOC>=:датН and  РегВозПост.DATE_TIME_IDDOC<:датК~)
     |                                    And
     |                                    ($ДокВозврСпис.ВидСписания = :ВидСписания)
     |                        ) ВозПост
     |                  On
  
Наверх
 
IP записан
 
Darlok
YaBB Newbies
*
Отсутствует


Знание - сила!

Сообщений: 8
Местоположение: Новосибирск
Зарегистрирован: 18. Сентября 2007
Пол: Мужской
Re: Мой первый прямой запрос SQL
Ответ #1 - 18. Сентября 2007 :: 11:08
Печать  
     |                     ТоварВ = Товар And ГодИзданияВ = ГодИздания And НомерИзданияВ = НомерИздания
     |   
//      Присоединяем таблицу, для определения цен приходов
     |                  Left outer Join
     |                        (
     |                        Select distinct
     |                              СпрДляМаг.ID as ТоварП,
     |                              $РегПриходЦены.ГодИздания as ГодИзданияП,
     |                              $РегПриходЦены.НомерИздания as НомерИзданияП,
     |                              Case
     |                                    When
     |                                          Sum($РегПриходЦены.Количество) = 0
     |                                    Then
     |                                          0
     |                                    Else
     |                                          Sum($РегПриходЦены.Сумма)/Sum($РегПриходЦены.Количество)
     |                              End as ЦенаПриходов
     |
     |                        From
     |                              $Регистр.ПриходЦены as РегПриходЦены (NOLOCK) 
//      Так как у нас в регистре "ПриходЦены", измерение типа неопределенный справочник, то присоединим таблица справочник.ДляМагазинов, нас интересует только эти значения
     |                  Left Join
     |                    $Справочник.ДляМагазинов СпрДляМаг On
     |                    $ВидСправочника36.ДляМагазинов + СпрДляМаг.ID = $РегПриходЦены.Товар
     |            
     |                        Group by СпрДляМаг.ID, $РегПриходЦены.ГодИздания, $РегПриходЦены.НомерИздания
     |
     |                        ) ПриходЦены
     |                  On
     |                     ТоварП = Товар And ГодИзданияП = ГодИздания And НомерИзданияП = НомерИздания
     |
//      Присоединим к временной таблице, справочник, используеться для определения входной цены, если не нашли в приходах, а также в условиях на тип издания выбираемых в форме отчета
     |                  Inner Join
     |                        $Справочник.ДляМагазинов СпрНоменклатур
     |                  On
     |                        СпрНоменклатур.ID = Товар
     |
     |                  Group By tmp.Клиент ,tmp.Товар, tmp.ГодИздания, tmp.НомерИздания, tmp.ЦенаПродаж
       |";

//      Добавим колонку в группировку, она нужна если мы будем использовать условия на "тип издания"
       Если ТипИзданий <> 3 Тогда
           ТекстЗапроса      = ТекстЗапроса + "
     |                                                                                                                                          ,$СпрНоменклатур.ТипИздания";
     КонецЕсли;

     ТекстЗапроса      = ТекстЗапроса + "
     |
//      Уберем лишнее из талблицы, т.к. нулевые продажи нам не интересны
     |                  Having
     |                        Sum(
     |                              Case
     |                                    When
     |                                          (ВозПост.ТоварВ is Null)
     |                                    Then
     |                                          (tmp.КолВоИнвРасход - tmp.КолВоИнвПриход)
     |                                    Else
     |                                          (tmp.КолВоНачОст + tmp.КолВоПриход - tmp.КолВоРасход)
     |                              End
     |                        ) <> 0
     |";

//      Накладываем условия на "Тип издания" при необходимости в зависимости от выбранных параметров в настойке отчета
     Если ТипИзданий = 1 Тогда
           ТекстЗапроса      = ТекстЗапроса + "
     |                        and $СпрНоменклатур.ТипИздания = 2";
     ИначеЕсли  ТипИзданий = 2 Тогда
           ТекстЗапроса      = ТекстЗапроса + "
     |                        and $СпрНоменклатур.ТипИздания = 1";
     КонецЕсли;

     ТекстЗапроса      = ТекстЗапроса + "
     |
     |            ) as tmp2
     |   
//      Сворачиваем таблицу, больше нам не нужна детализация по номеру и году издания
     |            Group By tmp2.Клиент ,tmp2.Товар
     |   
     |   
     |      ) as Результат
     |   
//      Присоединяем справочник "Группы", нужен для группировки результирующего отчета по "Тематике"
     |      Inner Join
     |         $Справочник.ДляМагазинов СпрНоменклатур
     |      On
     |            СпрНоменклатур.ID = Товар
     |   
//      Сворачиваем и упорядовачиваем таблицу, теперь нам не нужна детализация по клиентам
     |      Group By $СпрНоменклатур.Группы,Результат.Товар
     |      Order By $СпрНоменклатур.Группы,Результат.Товар
     |";
     
     ВремДата=(НачМесяца(НачДата)-1);

//      Устанавливаем переменные которые будут использованы в запросе
     //+" 00:00:00";   
     ДирКон.УстановитьТекстовыйПараметр("ВидСписания", Перечисление.ВидыСписания.ВозвратПоГрафику);
     ДирКон.УстановитьТекстовыйПараметр("датН", НачДата);
     ДирКон.УстановитьТекстовыйПараметр("датК", КонДата);
     ДирКон.УстановитьТекстовыйПараметр("ДатаОстатков", ДатаОстатков);
     ДирКон.УстановитьТекстовыйПараметр("ДатаНачОстатков", НачМесяца(НачДата)); 
     //ДирКон.Отладка(1);
     ТЗ = ДирКон.ВыполнитьИнструкцию(ТекстЗапроса);
     
    ;
     Возврат ТЗ;
КонецФункции // ПолучитьЗапросомСКЛ

  
Наверх
 
IP записан
 
Вадимко
God Member
*****
Отсутствует


Нам бы чего про ОдноЦэ...

Сообщений: 1048
Местоположение: Минск
Зарегистрирован: 24. Мая 2006
Пол: Мужской
Re: Мой первый прямой запрос SQL
Ответ #2 - 18. Сентября 2007 :: 18:42
Печать  
Превосходно, но имхо можно гораздо короче, особенно если использовать ВТ  Подмигивание (вот только может не всегда вписаться)
И КодОперации завести в регистре - Инвентаризация, Приход и проч.
  

Кампутер, кофе и сигареты - это очень плохо для моего здоровья...
Наверх
IP записан
 
Darlok
YaBB Newbies
*
Отсутствует


Знание - сила!

Сообщений: 8
Местоположение: Новосибирск
Зарегистрирован: 18. Сентября 2007
Пол: Мужской
Re: Мой первый прямой запрос SQL
Ответ #3 - 19. Сентября 2007 :: 02:44
Печать  
Вадимко
Пробовал наложить условия на вид документа через ВТ, ничего не получилось.

Структуру данных накладно изменять из соображений что конфигурация считаеться готовым продуктом, и типа подобные (добавление изменения в регистр) изменения могут быть внесены только при особых условиях.

Спасибо за ответ Улыбка
  
Наверх
 
IP записан
 
yudin
Full Member
***
Отсутствует


Краткость - с.т.

Сообщений: 131
Местоположение: Ростов - на - Дону
Зарегистрирован: 25. Мая 2006
Пол: Мужской
Re: Мой первый прямой запрос SQL
Ответ #4 - 25. Сентября 2007 :: 10:36
Печать  
ВТ не умеет фильтровать движения - приход расход только полностью. Если нужны движения, отфильтрованные по реквизитам или по виду документа, нужно отдельно посчитать отстатки с помощью ВТ,а  движения выдернуть из таблицы движений.

Добрые разработчики, может можно добавить новую виртуальную таблицу, в которой можно наложить условия по реквизиту регистра для отбора движений? Было бы так вкусно...  Круглые глаза
  

С уваженьем, дата, подпись
Наверх
wwwICQ  
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать