Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Горячая тема (более 10 ответов) Как избавится от лишних строк в результате (число прочтений - 2850 )
Betas
Junior Member
**
Отсутствует



Сообщений: 24
Зарегистрирован: 10. Октября 2008
Пол: Мужской
Как избавится от лишних строк в результате
20. Ноября 2008 :: 11:33
Печать  
Добрый день.
База dbf (не типовая), провайдер VFPOLEDB.
Делаю альтернативный журнал документов. Каждая строка документа связана с уникальным элементом справочника (СторонниеДокументы). Нужно, чтобы результат запроса содержал поля со значениями флагов по принципу:
если для всех строк документа реквизит этого справочника равен 1, тогда 2
если для всех строк документа реквизит этого справочника равен 0, тогда 0,
если есть и 0 и 1, тогда 1.
Пока обрабатываю результат запроса, который содержит все строки документов (избыточная информация).

[code]      ТекстЗапроса = "
     |SELECT
     |      ОбщийЖурнал.CLOSED as Флаг,      
     |      ОбщийЖурнал.ISMARK as ФлагУ,      
     |      DTOS(ОбщийЖурнал.DATE) + ОбщийЖурнал.TIME as Ключ,
     |      ОбщийЖурнал.DATE as Дата,
     |      ОбщийЖурнал.TIME as Время,
     |      ШапкаЗаявки.iddoc as Заявка,
     |      ОбщийЖурнал.DOCNO as Номер,
     |      $ШапкаЗаявки.ВхДата as ВхДата,
     |      $ШапкаЗаявки.ВхНомер as ВхНомер,
     |      $ШапкаЗаявки.Обраб as ОбрСкл,
     |      спрКонтрагенты.DESCR as Контрагент,
     |      $ШапкаЗаявки.ДокСумма as Сумма,
     |      $СторонниеДокументы.ПолученТовар as ПолученТовар,
     |      $СторонниеДокументы.ПолученыДокументы as ПолученыДокументы,
     |      $СтрокиЗаявки.ИндексСтрокиЗаявки as ИндексСтрокиЗаявкиКод,
     |      спрПользователи.DESCR as Автор
     |
     |FROM
     |
     |      1SJourn as ОбщийЖурнал
     |
     |LEFT JOIN
     |      $Документ.ЗаявкаНаДоставку as ШапкаЗаявки
     |      ON
     |      ШапкаЗаявки.iddoc
     |=
     |      ОбщийЖурнал.iddoc
     |
     |LEFT JOIN
     |      $Справочник.Контрагенты as спрКонтрагенты
     |      ON
     |      спрКонтрагенты.id
     |=
     |      $ШапкаЗаявки.Контрагент
     |
     |LEFT JOIN
     |      $Справочник.Пользователи as спрПользователи
     |      ON
     |      спрПользователи.id
     |=
     |      ОбщийЖурнал.SP74
     |
     |LEFT JOIN
     |      $ДокументСтроки.ЗаявкаНаДоставку as СтрокиЗаявки
     |      ON
     |(
     |      СтрокиЗаявки.iddoc+STR(СтрокиЗаявки.lineno,4)
     |=
     |      ШапкаЗаявки.iddoc
     |)
     |
     |LEFT JOIN
     |      $Справочник.СторонниеДокументы as СторонниеДокументы
     |      ON
     |      СторонниеДокументы.ID = $СтрокиЗаявки.СторонниеДокументы
     |
     |WHERE
     |      (ОбщийЖурнал.IDDocDef + DTOS(ОбщийЖурнал.date) + ОбщийЖурнал.time + ОбщийЖурнал.IDDoc BETWEEN ($ВидДокумента.ЗаявкаНаДоставку + DTOS(:НачДата~~) + '               ')
     |      AND ($ВидДокумента.ЗаявкаНаДоставку + DTOS(:КонДата~~) +'ZZZZZZZZZZZZZZZ'))
     |AND
     |      (спрКонтрагенты.ID = '" + Фильтр +"')
     |";
[/code]
Прямые запросы начал использовать совсем недавно, возможно есть простое решение этой задачи?
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Как избавится от лишних строк в результате
Ответ #1 - 20. Ноября 2008 :: 12:31
Печать  
Подзапрос
Цитата:
ТекстПодзапроса = "
     |(SELECT  
     |  SUM(1.00) as  КолСтрокВДокументе ,
     |  SUM(ICASE($СторонниеДокументы.ПолученТовар=:ТоварПолучен,1.00,0.00)) as КолСтрокСПолученнымТоваром ,
   |  SUM(ICASE($СторонниеДокументы.ПолученыДокументы =:ДокументыПолучены,1.00,0.00)) as КолСтрокСПолученнымиДокументами  ,
     |  ОбщийЖурнал.iddoc  as  iddoc
     |
   |FROM
     |
     |      1SJourn as ОбщийЖурнал
     |
   |LEFT JOIN
     |      $ДокументСтроки.ЗаявкаНаДоставку as СтрокиЗаявки
     |      ON
     |(
     |      СтрокиЗаявки.iddoc+STR(СтрокиЗаявки.lineno,4)
     |=
     |      ОбщийЖурнал.iddoc
     |)
     |
     |LEFT JOIN
     |      $Справочник.СторонниеДокументы as СторонниеДокументы
     |      ON
     |      СторонниеДокументы.ID = $СтрокиЗаявки.СторонниеДокументы  
     |
     |
   |WHERE
     |      (ОбщийЖурнал.IDDocDef + DTOS(ОбщийЖурнал.date) + ОбщийЖурнал.time + ОбщийЖурнал.IDDoc BETWEEN ($ВидДокумента.ЗаявкаНаДоставку + DTOS(:НачДата~~) + '               ')
     |      AND ($ВидДокумента.ЗаявкаНаДоставку + DTOS(:КонДата~~) +'ZZZZZZZZZZZZZZZ'))
     
     |GROUP BY  ОбщийЖурнал.iddoc
     | ) as  Подзапрос


Потом смотришь,
если КолСтрокВДокументе >КолСтрокСПолученнымТоваром  тогда то-то и то-то
и т.п.

P.S> Круто, в первом же запросе использовать индексы
P.S> По хорошему еще надо на NULL $СторонниеДокументы.id проверять в ICASE
  
Наверх
 
IP записан
 
Betas
Junior Member
**
Отсутствует



Сообщений: 24
Зарегистрирован: 10. Октября 2008
Пол: Мужской
Re: Как избавится от лишних строк в результате
Ответ #2 - 20. Ноября 2008 :: 13:10
Печать  
Большое спасибо, буду пробовать.
Только немного смущает (с точки зрения времени выполнения) дополнительное обращение к таблице общего журнала.
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Как избавится от лишних строк в результате
Ответ #3 - 20. Ноября 2008 :: 13:16
Печать  
Betas писал(а) 20. Ноября 2008 :: 13:10:
Большое спасибо, буду пробовать.
Только немного смущает (с точки зрения времени выполнения) дополнительное обращение к таблице общего журнала.


Ну в журнале индекс по iddoc еще есть.  Слабо поэтому повлияет.
Либо в подзапрос внести все нужные поля из журнала и по ним также группировать.
« Последняя редакция: 20. Ноября 2008 :: 15:18 - kiruha »  
Наверх
 
IP записан
 
Betas
Junior Member
**
Отсутствует



Сообщений: 24
Зарегистрирован: 10. Октября 2008
Пол: Мужской
Re: Как избавится от лишних строк в результате
Ответ #4 - 20. Ноября 2008 :: 15:34
Печать  
Не знаю, все ли правильно.
Запрос работает, количество строк в результате соответствует количеству документов.
Но тест на быстродействие (по сети, сеансов больше одного) показывает примерно одинаковое время выполнения по сравнению с запросом по старому варианту (там, где много строк). Если совсем не залезать в табл. часть, скорость выше в 3-4 раза. Надеялся получить нечто среднее.
[code]ТекстЗапроса = "
     |SELECT
     |      ОбщийЖурнал.CLOSED as Флаг,      
     |      ОбщийЖурнал.ISMARK as ФлагУ,      
     |      DTOS(ОбщийЖурнал.DATE) + ОбщийЖурнал.TIME as Ключ,
     |      ОбщийЖурнал.DATE as Дата,
     |      ОбщийЖурнал.TIME as Время,
     |      ШапкаЗаявки.iddoc as Заявка,
     |      ОбщийЖурнал.DOCNO as Номер,
     |      $ШапкаЗаявки.ВхДата as ВхДата,
     |      $ШапкаЗаявки.ВхНомер as ВхНомер,
     |      $ШапкаЗаявки.Обраб as ОбрСкл,
     |      спрКонтрагенты.DESCR as Контрагент,
     |      $ШапкаЗаявки.ДокСумма as Сумма,
     |
     |      ICASE(Подзапрос.КолСтрокСПолученнымТоваром = 0,0,ICASE(Подзапрос.КолСтрокСПолученнымТоваром = Подзапрос.КолСтрокВДокументе,1,2)) as ФлагПолДок,
     |      ICASE(Подзапрос.КолСтрокСПолученнымиДокументами = 0,0,ICASE(Подзапрос.КолСтрокСПолученнымиДокументами = Подзапрос.КолСтрокВДокументе,1,2)) as ФлагПолТовар,
     |
     |      спрПользователи.DESCR as Автор
     |FROM
     |
     |      1SJourn as ОбщийЖурнал
     |
     |LEFT JOIN
     |      $Документ.ЗаявкаНаДоставку as ШапкаЗаявки
     |      ON
     |      ШапкаЗаявки.iddoc
     |=
     |      ОбщийЖурнал.iddoc
     |
     |LEFT JOIN
     |      $Справочник.Контрагенты as спрКонтрагенты
     |      ON
     |      спрКонтрагенты.id
     |=
     |      $ШапкаЗаявки.Контрагент
     |
     |LEFT JOIN
     |      $Справочник.Пользователи as спрПользователи
     |      ON
     |      спрПользователи.id
     |=
     |      ОбщийЖурнал.SP74
     |
//      |****************************************************************
     |LEFT JOIN
     |(SELECT  
     |  SUM(1.00) as  КолСтрокВДокументе ,
     |  SUM(ICASE($СторонниеДокументы.ПолученТовар=1,1.00,0.00)) as КолСтрокСПолученнымТоваром,
     |  SUM(ICASE($СторонниеДокументы.ПолученыДокументы =1,1.00,0.00)) as КолСтрокСПолученнымиДокументами,
     |  ОбщийЖурнал1.iddoc  as  iddoc
     |
     |FROM
     |
     |      1SJourn as ОбщийЖурнал1
     |
     |LEFT JOIN
     |      $ДокументСтроки.ЗаявкаНаДоставку as СтрокиЗаявки
     |      ON
     |(
     |      СтрокиЗаявки.iddoc+STR(СтрокиЗаявки.lineno,4)
     |=
     |      ОбщийЖурнал1.iddoc
     |)
     |
     |LEFT JOIN
     |      $Справочник.СторонниеДокументы as СторонниеДокументы
     |      ON
     |      СторонниеДокументы.ID = $СтрокиЗаявки.СторонниеДокументы  
     |
     |
     |WHERE
     |      (ОбщийЖурнал1.IDDocDef + DTOS(ОбщийЖурнал1.date) + ОбщийЖурнал1.time + ОбщийЖурнал1.IDDoc BETWEEN ($ВидДокумента.ЗаявкаНаДоставку + DTOS(:НачДата~~) + '               ')
     |      AND ($ВидДокумента.ЗаявкаНаДоставку + DTOS(:КонДата~~) +'ZZZZZZZZZZZZZZZ'))
     |
     |GROUP BY  ОбщийЖурнал1.iddoc
     | ) as  Подзапрос
     |      ON
     |      Подзапрос.iddoc = ШапкаЗаявки.iddoc
//      |****************************************************************
     |
     |WHERE
     |      (ОбщийЖурнал.IDDocDef + DTOS(ОбщийЖурнал.date) + ОбщийЖурнал.time + ОбщийЖурнал.IDDoc BETWEEN ($ВидДокумента.ЗаявкаНаДоставку + DTOS(:НачДата~~) + '               ')
     |      AND ($ВидДокумента.ЗаявкаНаДоставку + DTOS(:КонДата~~) +'ZZZZZZZZZZZZZZZ'))[/code]
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Как избавится от лишних строк в результате
Ответ #5 - 20. Ноября 2008 :: 16:09
Печать  
Ну так строк в табличной части видимо больше раза в 3-4 чем документов этого вида.
Это еще хороший результат - видимо строк в среднем не так уж и много  Подмигивание

Либо, если скорость критична - делать еще справочник жестко привязанный не к строкам, а к просто документу.

По запросу - лучше From делать из подзапроса, а
ОбщийЖурнал присоединять  по iddoc - незначительно улучшит.
Можно условие по контрагенту в подзапрос еще втиснуть - тоже немного ускорит, если контрагент задан.
  
Наверх
 
IP записан
 
Betas
Junior Member
**
Отсутствует



Сообщений: 24
Зарегистрирован: 10. Октября 2008
Пол: Мужской
Re: Как избавится от лишних строк в результате
Ответ #6 - 20. Ноября 2008 :: 19:46
Печать  
Скорость критична, т.к. информация в журнале обновляется автоматически при изменении любого документа данного вида вне зависимости от присутствия его в видимых строках (к сожалению не sql и табличное поле используется через ТЗ).

Один справочник, содержащий информацию о состоянии справочников для строк решит вопрос скорости, но информация в нем не всегда будет достоверной, т.к. база распределенная и изменения в документе вносятся в центральной базе, а признаки получения товара/документов устанавливаются в периферийной прямо на форме документа, но независимо от него.

Сейчас элементы справочников для строк создаются при записи документа и больше в центральной базе не модифицируются. Если использовать один справочник для документа, то при добавлении/удалении строки нужно будет менять его реквизиты в центральной базе, и если между обменом справочник будет модифицирован и в периферийной, то эти изменения будут утрачены.  

По запросу.
К сожалению, не знаю азов и на получение информации об элементарных вещах приходится тратить очень много времени (кстати, очень помогла тема «Использование индексов …»).  Для меня к сожалению не очевидно, как присоединить в  подзапросе ОбщийЖурнал по iddoс. Пробовал использовать  iddoс из основного запроса, выдает ошибку.
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Как избавится от лишних строк в результате
Ответ #7 - 20. Ноября 2008 :: 20:39
Печать  
Код
Выбрать все
FROM (...) as  Подзапрос
LEFT JOIN 1SJourn as ОбщийЖурнал ON  ОбщийЖурнал .iddoc=Подзапрос.iddoc
 


все остальное одинаково.

При изменении каждого документа обновлять смысла нет.
Только раз в 60 сек или при активации формы (это если пользователь провел или изменил
докумет текущего журнала) - Formex

Вообще табличное поле здесь быстрее на порядки - т.к. обновляются только видимые строки,
а их соответственно меньше на порядки.

На SqlLite уже готово- http://www.1cpp.ru/forum/YaBB.pl?num=1214205575

На OleDb для Fox у меня есть "рыба" на базе
ProxyDataProvider trad-а
http://www.1cpp.ru/forum/YaBB.pl?num=1210942597
могу поправить ошибки и выложить (до понедельника предположительно)
Сделано ввиде класса - т.е. можно править на свое усмотрение.
  
Наверх
 
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как избавится от лишних строк в результате
Ответ #8 - 21. Ноября 2008 :: 06:37
Печать  
kiruha писал(а) 20. Ноября 2008 :: 20:39:
На SqlLite уже готово- http://www.1cpp.ru/forum/YaBB.pl?num=1214205575

На OleDb для Fox у меня есть "рыба" на базе
ProxyDataProvider trad-а
http://www.1cpp.ru/forum/YaBB.pl?num=1210942597
могу поправить ошибки и выложить (до понедельника предположительно)
Сделано ввиде класса - т.е. можно править на свое усмотрение.

На SqlLite пока нету БыстрогоПоиска, но Саша обещал посмотреть.
Кирилл, а ты смог сделать БыстрыйПоиск?
Как мне кажется, без этого функционала вообще не стоит заморачиваться с подменой списков справочников и журналов документов.
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Как избавится от лишних строк в результате
Ответ #9 - 21. Ноября 2008 :: 07:48
Печать  
JohnyDeath писал(а) 21. Ноября 2008 :: 06:37:
kiruha писал(а) 20. Ноября 2008 :: 20:39:
На SqlLite уже готово- http://www.1cpp.ru/forum/YaBB.pl?num=1214205575

На OleDb для Fox у меня есть "рыба" на базе
ProxyDataProvider trad-а
http://www.1cpp.ru/forum/YaBB.pl?num=1210942597
могу поправить ошибки и выложить (до понедельника предположительно)
Сделано ввиде класса - т.е. можно править на свое усмотрение.

На SqlLite пока нету БыстрогоПоиска, но Саша обещал посмотреть.
Кирилл, а ты смог сделать БыстрыйПоиск?
Как мне кажется, без этого функционала вообще не стоит заморачиваться с подменой списков справочников и журналов документов.


В принципе поэтому и отложил - лично меня больше интересуют формы списка справочников, чем журналы.
Но Trad недавно же добавил
trad писал(а) 20. Сентября 2008 :: 09:06:
релиз 1.1.0.2
Выполнена небольшая доработка для осуществления обратной связи с контролом ТП. (например для реализации QS)

Интерфейс дополнен методами:
OnFieldsChanged()
SetCurrentRow(Row)
ResetData(Row)
- эти методы реализованы у специального класса BaseDataProvider, который может быть базовым для КОП-поставщика.
Описание методов см. sdk по поставщикам ТП.
ВК и исходники на своих местах.

небольшой шаблон-пример для QS:
Код
Выбрать все
Функция GetQuickSearchType(ИмяПоля) Экспорт
    Возврат 1; //0-поиска нет, 1-поиск текстовый
КонецФункции

Процедура QuickSearch(ИмяПоля,ТипПоиска,Данные) Экспорт
    //выполняем поиск строки по специфичному для текущего поставщика алгоритму
    Row = ... //в итоге получаем объект идентифицирующий строку
    Сам().SetCurrentRow(Row); //вызов callback метода интерфейса
КонецПроцедуры 


  
Наверх
 
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как избавится от лишних строк в результате
Ответ #10 - 21. Ноября 2008 :: 08:41
Печать  
Да, я видел, что он это уже добавил, но я не знаю как это реализовать  на ОлеДб Смущённый
  
Наверх
 
IP записан
 
Betas
Junior Member
**
Отсутствует



Сообщений: 24
Зарегистрирован: 10. Октября 2008
Пол: Мужской
Re: Как избавится от лишних строк в результате
Ответ #11 - 21. Ноября 2008 :: 09:38
Печать  
На SqlLite пробовал, получилось заметно медленнее, чем на Fox (по сети, не терминал, пользователей больше одного, выборки по остаткам регистра, по документам), причем скорость SqlLite (в отличие от Fox) резко снижается именно при подключении второго, пусть даже пассивного пользователя.

Использую именно ТП, но не знал о возможности использования поставщика с обратной связью на OleDb для Fox. Если есть «рыба», будет очень интересно попробовать (хотя так глубоко еще не влезал).

По поводу интервала обновления. Сейчас 10 сек (тестировал, хоть и нет необходимости, при снижении до 0,5 сек). Если интервал журнала такой, что в выборке до 1000 документов и документы меняются не слишком часто, особых подвисаний нет. Обновление идет только тогда, когда форма активна и в два этапа. Вначале очень быстрая проверка на признак изменения документов конкретного вида, и только если изменения есть, полное обновление данных. Пока, к сожалению, по всему интервалу, а не только тех, которые видны.

Подмену отдельных журналов, как мне кажется,  есть смысл делать даже без заметного выигрыша в скорости, уже потому, что можно легко использовать произвольные множественные фильтры и сортировки.

P.S. Спасибо за подсказку.
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать