Имя: Пароль:
1C
1C 7.7
v7: Помогите оптимизировать прямой запрос
0 Zhuravlik
 
24.09.12
10:16
Добрый день. Хотел сделать прямым запросом поиск документа по периодическому реквизиту справочника, и группировку по атрибутам документа, по строке документа по которой было движение.
Проблема в том, что есть несколько видов документов с одинаковой структурой, каждый из которых может быть документом движения периодического реквизита.
Если мне эти группировки по атрибутам получать штатно, то все портит метод ПолучитьСтрокуПоНомеру - периодический реквизит я нахожу быстро, а вот атрибуты по строке документа получаю долго.
Возникла мысль сделать это все прямым запросом. Путем долгих манипуляций получилось так:


   спАвто = СоздатьОбъект("СписокЗначений");

   спрАвтомобили = СоздатьОбъект("Справочник.Автомобили");
   спрАвтомобили.ВыбратьЭлементы();
   Пока спрАвтомобили.ПолучитьЭлемент() = 1 Цикл
       
       спАвто.ДобавитьЗначение(спрАвтомобили.ТекущийЭлемент());
       
       Если спАвто.РазмерСписка() = 10 Тогда
           Прервать;
       КонецЕсли;
       
   КонецЦикла;
   
   база = СоздатьОбъект("SQLiteBase");
   база.Открыть(":memory:");
   Запрос = база.НовыйЗапрос();
   запрос.ВыполнитьЗапрос("PRAGMA journal_mode = OFF");    
   база.УложитьОбъекты(спАвто, "spAvto");    

   ТекстЗапроса = "
   |Select
   |   spAvto.val as [Автомобиль $Справочник.Автомобили],
   |   Период.DATE as DATE,
   |   Период.DOCID as [Doc $Документ],
   |   Период.TIME as TIME,
   |   Период.LINENO as LINENO,
   |";
   
   Для сч=2009 По 2013 Цикл
       
       ТекстЗапроса = ТекстЗапроса + "
       |DocTAB_" + сч + ".Вариант As [Вариант" + сч + " $Справочник.Авто_Варианты],
       |DocTAB_" + сч + ".Модель As [Модель" + сч + " $Справочник.Авто_Модели],
       |DocTAB_" + сч + ".Модификация As [Модификация" +сч + " $Справочник.Авто_Модификации],
       |DocTAB_" + сч + ".Цвет As [Цвет" + сч +  " $Справочник.Авто_Цвета],";
       
   КонецЦикла;
   
   ТекстЗапроса = ТекстЗапроса +
   
   "
   |    jour.iddocDef as Doc_kind
   |From [_1S.Const] as Период,
   |      spAvto
   |Left join Journal as jour on Jour.IDDoc = Период.DOCID
   |";
   
   Для сч=2009 по 2013 Цикл
       ТекстЗапроса = ТекстЗапроса + "Left join [ДокументСтроки.ВАИ_ДанныеВБазу_"+ сч +"] As DocTAB_"+ сч +" on DocTAB_"+ сч +".Автомобиль = spAvto.val
       |and DocTAB_"+ сч +".LINENO = Период.LINENO" + РазделительСтрок;
   КонецЦикла;

   ТекстЗапроса = ТекстЗапроса +
   "Where Период.id = :ИсторияРеквизита.Автомобили.Загружен and Период.objid = spAvto.val";    

   ТЗ = Запрос.ВыполнитьЗапрос(ТекстЗапроса);
1 Zhuravlik
 
24.09.12
10:17
+Помогите пожалуйста оптимизировать этот запрос, чтобы было не несколько колонок на один атрибут, а одна.
т.е. не "Вариант2009, Вариант2010, Вариант2011, Вариант2012", а "Вариант"
2 Zhuravlik
 
24.09.12
10:18
+База ДБФ, запрос на 1SQlite.
3 Mikeware
 
24.09.12
10:18
(1) coalesce()
4 Mikeware
 
24.09.12
10:19
(2) тогда union all
5 Zhuravlik
 
24.09.12
10:31
(3) Пишу
Coalesce(Вариант2009, Вариант2010, Вариант2011, Вариант2012, Вариант2013) AS Вариант

Говорит - near "Coalesce": syntax error

А в дбфе (3) - не катит? Делать (4)?
6 Zhuravlik
 
24.09.12
10:38
Это код из Запрос.Отладка()

DocTAB_2009.Вариант As [Вариант2009 $Справочник.Авто_Варианты],
DocTAB_2009.Модель As [Модель2009 $Справочник.Авто_Модели],
DocTAB_2009.Модификация As [Модификация2009 $Справочник.Авто_Модификации],
DocTAB_2009.Цвет As [Цвет2009 $Справочник.Авто_Цвета],
DocTAB_2010.Вариант As [Вариант2010 $Справочник.Авто_Варианты],
DocTAB_2010.Модель As [Модель2010 $Справочник.Авто_Модели],
DocTAB_2010.Модификация As [Модификация2010 $Справочник.Авто_Модификации],
DocTAB_2010.Цвет As [Цвет2010 $Справочник.Авто_Цвета],
DocTAB_2011.Вариант As [Вариант2011 $Справочник.Авто_Варианты],
DocTAB_2011.Модель As [Модель2011 $Справочник.Авто_Модели],
DocTAB_2011.Модификация As [Модификация2011 $Справочник.Авто_Модификации],
DocTAB_2011.Цвет As [Цвет2011 $Справочник.Авто_Цвета],
DocTAB_2012.Вариант As [Вариант2012 $Справочник.Авто_Варианты],
DocTAB_2012.Модель As [Модель2012 $Справочник.Авто_Модели],
DocTAB_2012.Модификация As [Модификация2012 $Справочник.Авто_Модификации],
DocTAB_2012.Цвет As [Цвет2012 $Справочник.Авто_Цвета],
DocTAB_2013.Вариант As [Вариант2013 $Справочник.Авто_Варианты],
DocTAB_2013.Модель As [Модель2013 $Справочник.Авто_Модели],
DocTAB_2013.Модификация As [Модификация2013 $Справочник.Авто_Модификации],
DocTAB_2013.Цвет As [Цвет2013 $Справочник.Авто_Цвета],
   jour.iddocDef as Doc_kind
From [_1S.Const] as Период,
     spAvto
Left join Journal as jour on Jour.IDDoc = Период.DOCID
Left join [ДокументСтроки.ВАИ_ДанныеВБазу_2009] As DocTAB_2009 on DocTAB_2009.Автомобиль = spAvto.val
and DocTAB_2009.LINENO = Период.LINENO
Left join [ДокументСтроки.ВАИ_ДанныеВБазу_2010] As DocTAB_2010 on DocTAB_2010.Автомобиль = spAvto.val
and DocTAB_2010.LINENO = Период.LINENO
Left join [ДокументСтроки.ВАИ_ДанныеВБазу_2011] As DocTAB_2011 on DocTAB_2011.Автомобиль = spAvto.val
and DocTAB_2011.LINENO = Период.LINENO
Left join [ДокументСтроки.ВАИ_ДанныеВБазу_2012] As DocTAB_2012 on DocTAB_2012.Автомобиль = spAvto.val
and DocTAB_2012.LINENO = Период.LINENO
Left join [ДокументСтроки.ВАИ_ДанныеВБазу_2013] As DocTAB_2013 on DocTAB_2013.Автомобиль = spAvto.val
and DocTAB_2013.LINENO = Период.LINENO

Coalesce(Вариант2009, Вариант2010, Вариант2011, Вариант2012, Вариант2013) AS Вариант
Coalesce(Модель2009, Модель2010, Модель2011, Модель2012, Модель2013) AS Модель
Coalesce(Модификация2009, Модификация2010, Модификация2011, Модификация2012, Модификация2013) AS Модификация
Coalesce(Цвет2009, Цвет2010, Цвет2011, Цвет2012, Цвет2013) AS Цвет

Выдает ошибку "near "Coalesce": syntax error"
7 Ёпрст
 
24.09.12
11:03
(5)

1.катит
2.будет быстрее
8 Zhuravlik
 
24.09.12
11:05
(7) А что не так с синтаксисом в (6)?
9 Zhuravlik
 
24.09.12
11:07
+ Исправил на
Coalesce(DocTAB_.Вариант2009, DocTAB_.Вариант2010, DocTAB_.Вариант2011, DocTAB_.Вариант2012, DocTAB_.Вариант2013) AS [Вариант $Справочник.Авто_Варианты]

Теперь говорит no such column DocTAB_.Вариант2009
10 Zhuravlik
 
24.09.12
11:11
Вот текст запроса, для получения одного атрибута


Select
  spAvto.val as [Автомобиль $Справочник.Автомобили],
  Период.DATE as DATE,
  Период.DOCID as [Doc $Документ],
  Период.TIME as TIME,
  Период.LINENO as LINENO,

DocTAB_2009.Вариант As [Вариант2009 $Справочник.Авто_Варианты],
DocTAB_2010.Вариант As [Вариант2010 $Справочник.Авто_Варианты],
DocTAB_2011.Вариант As [Вариант2011 $Справочник.Авто_Варианты],
DocTAB_2012.Вариант As [Вариант2012 $Справочник.Авто_Варианты],
DocTAB_2013.Вариант As [Вариант2013 $Справочник.Авто_Варианты],
jour.iddocDef as Doc_kind,
Coalesce(Вариант2009, Вариант2010, Вариант2011, Вариант2012, Вариант2013) AS [Вариант $Справочник.Авто_Варианты]
From [_1S.Const] as Период, spAvto
Left join Journal as jour on Jour.IDDoc = Период.DOCID
Left join [ДокументСтроки.ВАИ_ДанныеВБазу_2009] As DocTAB_2009 on DocTAB_2009.Автомобиль = spAvto.val
Left join [ДокументСтроки.ВАИ_ДанныеВБазу_2010] As DocTAB_2010 on DocTAB_2010.Автомобиль = spAvto.val
Left join [ДокументСтроки.ВАИ_ДанныеВБазу_2011] As DocTAB_2011 on DocTAB_2011.Автомобиль = spAvto.val
Left join [ДокументСтроки.ВАИ_ДанныеВБазу_2012] As DocTAB_2012 on DocTAB_2012.Автомобиль = spAvto.val
Left join [ДокументСтроки.ВАИ_ДанныеВБазу_2013] As DocTAB_2013 on DocTAB_2013.Автомобиль = spAvto.val
Where Период.id = '  DO' and Период.objid = spAvto.val


Ругается  no such column: Вариант2009
11 Ёпрст
 
24.09.12
11:20
(10) и правильно делает, я тоже не в курсе, что у тебя такое Вариант2009.
12 Ёпрст
 
24.09.12
11:20
+11 ибо в табличке констант нет такого поля.
13 Zhuravlik
 
24.09.12
11:30
А он работает только с таблицами, указанными в "FROM"?
вот мой последний вариант:

Select
   spAvto.val as [Автомобиль $Справочник.Автомобили],
   Период.DATE as DATE,
   Период.DOCID as [Doc $Документ],
   Период.TIME as TIME,
   Период.LINENO as LINENO,
   DocTAB_2009.Вариант As [Вариант2009 $Справочник.Авто_Варианты],
   DocTAB_2010.Вариант As [Вариант2010 $Справочник.Авто_Варианты],
   DocTAB_2011.Вариант As [Вариант2011 $Справочник.Авто_Варианты],
   DocTAB_2012.Вариант As [Вариант2012 $Справочник.Авто_Варианты],
   DocTAB_2013.Вариант As [Вариант2013 $Справочник.Авто_Варианты],
   jour.iddocDef as Doc_kind
COALESCE(Вариант2009, Вариант2010, Вариант2011, Вариант2012, Вариант2013) AS [Вариант $Справочник.Авто_Варианты]
FROM [_1S.Const] as Период, spAvto
LEFT JOIN Journal as jour on Jour.IDDoc = Период.DOCID
LEFT JOIN [ДокументСтроки.ВАИ_ДанныеВБазу_2009] As DocTAB_2009 on DocTAB_2009.LINENO = Период.LINENO and DocTAB_2009.IDDOC = Период.DOCID
LEFT JOIN [ДокументСтроки.ВАИ_ДанныеВБазу_2010] As DocTAB_2010 on DocTAB_2010.LINENO = Период.LINENO and DocTAB_2010.IDDOC = Период.DOCID
LEFT JOIN [ДокументСтроки.ВАИ_ДанныеВБазу_2011] As DocTAB_2011 on DocTAB_2011.LINENO = Период.LINENO and DocTAB_2011.IDDOC = Период.DOCID
LEFT JOIN [ДокументСтроки.ВАИ_ДанныеВБазу_2012] As DocTAB_2012 on DocTAB_2012.LINENO = Период.LINENO and DocTAB_2012.IDDOC = Период.DOCID
LEFT JOIN [ДокументСтроки.ВАИ_ДанныеВБазу_2013] As DocTAB_2013 on DocTAB_2013.LINENO = Период.LINENO and DocTAB_2013.IDDOC = Период.DOCID
WHERE Период.id = '  DO' and Период.objid = spAvto.val
14 Zhuravlik
 
24.09.12
11:31
Но если я ставлю
COALESCE(DocTAB_2009.Вариант, DocTAB_2010.Вариант, DocTAB_2011.Вариант, DocTAB_2012.Вариант, DocTAB_2013.Вариант) AS [Вариант $Справочник.Авто_Варианты] после LEFT JOIN - тоже ругается на синтаксис
15 Zhuravlik
 
24.09.12
11:33
+ сейчас буду пробовать в лефт джойне делать селект, и там указывать коалисце.
16 Ёпрст
 
24.09.12
11:33
(13) еще раз, Вариант2009 - это что ?
(14)

что значит "после LEFT JOIN" ?
17 Zhuravlik
 
24.09.12
11:44
(16)
1.
В первом селекте я пишу:
SELECT
...
DocTAB_2009.Вариант As [*Вариант2009* $Справочник.Авто_Варианты],

т.е. Вариант2009 - это алиас для DocTAB_2009.
А DocTAB_2009 - это в свою очередь алиас для
LEFT JOIN [ДокументСтроки.ВАИ_ДанныеВБазу_2009] As DocTAB_2009 on DocTAB_2009.LINENO = Период.LINENO and DocTAB_2009.IDDOC = Период.DOCID

2. Это значит, что конструкцию Coalesce я пишу между SELECT и FROM, но если указываю ее между LEFT JOIN и WHERE - выскакивает та же ошибка. Я не знаю, важен порядок, или нет? Ее положение в  тексте запроса?
18 Zhuravlik
 
24.09.12
11:45
+ Извиняюсь,
* т.е. Вариант2009 - это алиас для DocTAB_2009.Вариант
19 Ёпрст
 
24.09.12
11:49
(17) да уж..

Select
..........
COALESCE(DocTAB_2009.Вариант,DocTAB_2010.Вариант ) AS [Вариант $Справочник.Авто_Варианты]
FROM [_1S.Const] as Период, spAvto
LEFT JOIN Journal as jour on Jour.IDDoc = Период.DOCID
LEFT JOIN [ДокументСтроки.ВАИ_ДанныеВБазу_2009] As DocTAB_2009 on DocTAB_2009.LINENO = Период.LINENO and DocTAB_2009.IDDOC = Период.DOCID
..............
20 Ёпрст
 
24.09.12
11:51
(18) а теперь подумай, что ты хотел выбирать вот тут:

select
Coalesce(Вариант2009, Вариант2010,

псевдонимы табличек ?

Ясен пень, что скуль лайт тебя послал в пешее путешествие с эротическим уклоном.
21 Mikeware
 
24.09.12
11:56
"Coalesce я пишу между SELECT и FROM" - это, конечно...
22 Zhuravlik
 
24.09.12
11:59
(20) Да, запутался... Получилось)))
(21) Порядок важен?

А подскажите пожалуйста, в отладке я вижу такие сообщения

Подбор индекса для таблицы 1SCONST:
   Ограничения: ID=; OBJID=;
   Найдено в кэше
   Выбран индекс IDD: ID+OBJID+DTOS(DATE)+TIME+DOCID+STR(PARTNO,3)
   Стоимость: 48

Стоимость - это время? в мс?
23 Mikeware
 
24.09.12
12:02
(22) это "место" - "между SELECT и FROM" - имеет свое название...
24 Zhuravlik
 
24.09.12
12:05
(23) Тело запроса?)
Кaк может человек ожидaть, что его мольбaм о снисхождении ответит тот, кто превыше, когдa сaм он откaзывaет в милосердии тем, кто ниже его? Петр Трубецкой