Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Горячая тема (более 10 ответов) Объединение двух запросов? Или можно иначе? (число прочтений - 6792 )
Mikeware
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 262
Зарегистрирован: 27. Июля 2006
Пол: Мужской
Объединение двух запросов? Или можно иначе?
07. Марта 2007 :: 11:00
Печать  
Наставьте на путь истинный...
Есть два запроса - запрос остатков по регистру. Один фильтрует по складу, другой по всем складам.
Код
Выбрать все
|select sum($p.Количество) from $РегистрИтоги.ОстаткиТМЦ p(nolock)
|where p.period = :Период~~ and $p.Склад = :ВыбСклад and $p.Номенклатура = :ВыбНоменклатура";
 

и
Код
Выбрать все
|select sum($p.Количество) from $РегистрИтоги.ОстаткиТМЦ p(nolock)
|where p.period = :Период~~  and $p.Номенклатура = :ВыбНоменклатура";
 


Можно ли объединить в одном запросе? Точнее, будет ли это быстрее, нежели два запроса?
И второй вопрос: Если использовать параметризованый запрос - непереданный параметр будет равен NULL ? Тогда стОит ли в запросе использовать case, или будет медленнее?
  
Наверх
ICQ  
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Объединение двух запросов? Или можно иначе?
Ответ #1 - 07. Марта 2007 :: 11:24
Печать  
Запросы с UNION ALL обычно хорошо параллелятся. Если у тебя многопроцессорный сервер - это не плохой вариант.
Так же (конкретно для этого запроса) желательно, чтобы Номенклатура была первым измерением, а Склад - вторым. Или чтобы была установлена галка "Отбор итогов" на Номенклатура.

При массовом вызове нужен RPCMode или подготовленные запросы.

ЗЫ:
Код
Выбрать все
select sum($p.Количество) весьостаток
	, sum(case when $p.Склад = :ВыбСклад then $p.Количество else 0 end) остатокпоскладу
from $РегистрИтоги.ОстаткиТМЦ p(nolock)
where p.period = :Период~~
	and $p.Номенклатура = :ВыбНоменклатура 

  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
Mikeware
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 262
Зарегистрирован: 27. Июля 2006
Пол: Мужской
Re: Объединение двух запросов? Или можно иначе?
Ответ #2 - 07. Марта 2007 :: 12:10
Печать  
Цитата:
Запросы с UNION ALL обычно хорошо параллелятся. Если у тебя многопроцессорный сервер - это не плохой вариант..
Да, сервер 2-процессорный. Попробую
Цитата:
Так же (конкретно для этого запроса) желательно, чтобы Номенклатура была первым измерением, а Склад - вторым. Или чтобы была установлена галка "Отбор итогов" на Номенклатура..
Именно _первым_ и _вторым_, или чтобы Склад шел за Номенклатура? Тогда так и есть - штатный регистр ТиСа Фирма,Номенклатура,Склад, ЦенаПрод
Цитата:
При массовом вызове нужен RPCMode или подготовленные запросы.
RPCMode - достаточно перед парамектризованым запросом поставить ODBCRecordSet.RPCMode(1) или надо что-то еще?
-----------
Забыл сказать спасибо, и спросить - где б  почитать, или примерчики... А то из БОЛ - сильно абстрактны для моего среднего ума Печаль
  
Наверх
ICQ  
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Объединение двух запросов? Или можно иначе?
Ответ #3 - 07. Марта 2007 :: 12:30
Печать  
Mikeware писал(а) 07. Марта 2007 :: 12:10:
Именно _первым_ и _вторым_, или чтобы Склад шел за Номенклатура? Тогда так и есть - штатный регистр ТиСа Фирма,Номенклатура,Склад, ЦенаПрод

Именно первым и вторым, иначе ты не попадаешь в индекс. Стоит добавить отбор по фирме или добавить подходящий тебе индекс, установив "Отбор итогов" на Номенклатура.

Mikeware писал(а) 07. Марта 2007 :: 12:10:
Цитата:
При массовом вызове нужен RPCMode или подготовленные запросы.
RPCMode - достаточно перед парамектризованым запросом поставить ODBCRecordSet.RPCMode(1) или надо что-то еще?

"парамектризованым" - понятие растяжимое. Подмигивание Для подготовленных запросов RPCMode не нужен. Поэтому я и написал "или".
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
Mikeware
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 262
Зарегистрирован: 27. Июля 2006
Пол: Мужской
Re: Объединение двух запросов? Или можно иначе?
Ответ #4 - 07. Марта 2007 :: 13:11
Печать  
berezdetsky писал(а) 07. Марта 2007 :: 12:30:
Именно первым и вторым, иначе ты не попадаешь в индекс. Стоит добавить отбор по фирме или добавить подходящий тебе индекс, установив "Отбор итогов" на Номенклатура.
Дуракам везет. Такой индекс уже есть.  т.к. штатно есть отбор итогов...
Цитата:
"параметризованым" - понятие растяжимое. Подмигивание Для подготовленных запросов RPCMode не нужен. Поэтому я и написал "или".

про RPC почитаю еще...
  
Наверх
ICQ  
IP записан
 
Mikeware
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 262
Зарегистрирован: 27. Июля 2006
Пол: Мужской
Re: Объединение двух запросов? Или можно иначе?
Ответ #5 - 10. Мая 2007 :: 08:32
Печать  
А почему при зменении параметра :Период~~ с текстового на SQL-ный запрос перестает работать?
Т.е.
Код
Выбрать все
 |declare @Склад char(9)
|declare @Товар char(9)
|declare @Заявка char(9)
|set @Товар = ?
|set @Склад = ?
|set @Заявка = ?  
|select sum($p.Количество) [ВесьОстаток] , sum(case when $p.Склад = @Склад then $p.Количество else 0 end) [ОстатокПоСкладу],  0 [ВесьРезерв] , 0 [РезервПоЗаявке]
|from $РегистрИтоги.ОстаткиТМЦ p(nolock) where p.period = :Период~~  and $p.Номенклатура = @Товар  


работает, а
Код
Выбрать все
|declare @Склад char(9)
|declare @Товар char(9)
|declare @Заявка char(9)
|declare @ПериодОстатков datetime
|set @Товар = ?
|set @Склад = ?
|set @Заявка = ?  
|set @ПериодОстатков = ?  
|select sum($p.Количество) [ВесьОстаток] , sum(case when $p.Склад = @Склад then $p.Количество else 0 end) [ОстатокПоСкладу],  0 [ВесьРезерв] , 0 [РезервПоЗаявке]
|from $РегистрИтоги.ОстаткиТМЦ p(nolock) where p.period = @ПериодОстатков and $p.Номенклатура = @Товар
 

- не хочет?
  
Наверх
ICQ  
IP записан
 
Mikeware
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 262
Зарегистрирован: 27. Июля 2006
Пол: Мужской
Re: Объединение двух запросов? Или можно иначе?
Ответ #6 - 10. Мая 2007 :: 08:52
Печать  
ПРОверил в КвА - работает , гад....
Где ж собака порылась? тут-
Код
Выбрать все
Период=ЗапросОстатковРезервов.MD.GetBegOfPeriod(ТекПериод);
Если ЗапросОстатковРезервов.Prepare(ТекстСводногоЗапроса2)=0 Тогда
Предупреждение("Не подготовился запрос r());
Возврат;
КонецЕсли;
ЗапросОстатковРезервов.AddParam(1,14,9,0);
ЗапросОстатковРезервов.AddParam(1,14,9,0);
ЗапросОстатковРезервов.AddParam(1,14,9,0);
ЗапросОстатковРезервов.AddParam(1,10,10,0);

ЗапросОстатковРезервов.SetParam(1,Номенклатура);
ЗапросОстатковРезервов.SetParam(2,Склад);
ЗапросОстатковРезервов.SetParam(3,Заявка);
ЗапросОстатковРезервов.SetParam(4,Период);
 

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


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Объединение двух запросов? Или можно иначе?
Ответ #7 - 10. Мая 2007 :: 11:25
Печать  
Возможно, собака порылась здесь: Цитата:
ЗапросОстатковРезервов.AddParam(1,10,10,0);

10, если верить документации, обозначает timestamp, а тип поля - datetime.

У меня когда-то не получилось Ужас передать дату в подготовленный запрос. С тех пор я передаю её как char(8).
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
DmitrO
1c++ power user
Отсутствует


ex developer

Сообщений: 579
Местоположение: г. Киров
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Объединение двух запросов? Или можно иначе?
Ответ #8 - 10. Мая 2007 :: 12:54
Печать  
Цитата:
10, если верить документации, обозначает timestamp, а тип поля - datetime.

10 это SQL_TYPE_TIMESTAMP, это одибисишный тип который для MSSQL соответствует типу datetime, а не timestamp.
Дело в том, что следующим параметром необходимо указать длину буфера в байтах, которая должна быть не меньше длины структуры SQL_TIMESTAMP_STRUCT.
Т.е. так надо:
ЗапросОстатковРезервов.AddParam(1,10,20,0);

Просто раньше timestamp поля имели природу дата+время+доли секунды, и разрабатывая стандарт ODBC такой тип назвали SQL_TYPE_TIMESTAMP, потом в след. версиях mssql поля типа timestamp перестали иметь природу даты а стали просто длинными числами. Отсюда путаница.
Пример ODBC литерала для mssql типа datetime: {ts '2007-05-10 16:54:38.345'}
  
Наверх
ICQ  
IP записан
 
Mikeware
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 262
Зарегистрирован: 27. Июля 2006
Пол: Мужской
Re: Объединение двух запросов? Или можно иначе?
Ответ #9 - 10. Мая 2007 :: 14:46
Печать  
Не работает .AddParam(1,10,20,0);
попробовад вывести то, во что транслится это значение -  cast( @ПериодОстатков as char(30))  [РезПериод] - пустая строка, а если @ПериодОстатков  [РезПериод] - то '  .  .  '
Чего ж я не так делаю? ПРОбовал и AddParam(1,10,22,0);

выхожу на асфальт я, в лыжи обутый...
  
Наверх
ICQ  
IP записан
 
Mikeware
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 262
Зарегистрирован: 27. Июля 2006
Пол: Мужской
Re: Объединение двух запросов? Или можно иначе?
Ответ #10 - 11. Мая 2007 :: 03:16
Печать  
Перезагрузил комп. Заработало.
  
Наверх
ICQ  
IP записан
 
Mikeware
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 262
Зарегистрирован: 27. Июля 2006
Пол: Мужской
Re: Объединение двух запросов? Или можно иначе?
Ответ #11 - 11. Мая 2007 :: 08:29
Печать  
ПОпытался совместить два запроса - через union  вываливаетсяс ошибкой - "не могу обработать запрос... "
А выборкой одновременно из двух таблиц - фигня получается.... Цифры ниоткуда...
Код
Выбрать все
|select
|    sum($p.Количество) [ВесьОстаток],
|    sum(case when $p.Склад = @Склад then $p.Количество else 0 end)  [ОстатокПоСкладу],
|    sum(case when $pp.Склад = @Склад then $pp.Количество else 0 end) [ВесьРезерв],
|    sum(case when $pp.ЗаявкаПокупателя = @Заявка  then $pp.Количество else 0 end) [РезервПоЗаявке]
|from $РегистрИтоги.ОстаткиТМЦ p(nolock),$РегистрИтоги.РезервыТМЦ pp(nolock)
|  where p.period = @ПериодОстатков and $p.Номенклатура = @Товар
|   and pp.period = @ПериодОстатков and $pp.Номенклатура = @Товар
 

  
Наверх
ICQ  
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать