Имя: Пароль:
1C
1C 7.7
v7: Преобразование вида в SQL из даты в строку по маске
, ,
0 Lacoster
 
03.07.13
10:44
Необходимо из РегистраОстатков и оборотов достать данные.
Но сначал необходимо узнать начало периода. Начало периода нахожу путем отнимания дней из договора от сегодня.
Запрос с получением дней работает отлично. А вот все вместе отказывается. А отказывается потому что в строке |From  $РегистрОстаткиОбороты.Покупатели((Договор.НачПер), .....
(Договор.НачПер) должно быть строкой в виде ггггММдд, а там у меня дата в виде дд-мм-гггг. Как мне преобразовать вид в нужный мне?
А то я эту дату получаю заранее, циклом бегу по датам и каждый раз отрабатываю запрос. Времени тратиться уйма! Решил ускорить и вот проблема.

|Select
   |Рег.Договор [Договор $Справочник.Договоры],
   |    Рег.СуммаРубНачальныйОстаток as  СуммаРубНачОст,
   |    Рег.СуммаРубПриход          as  СуммаРубПриход,
   |    Рег.СуммаРубРасход          as  СуммаРубРасход,
   |    Рег.СуммаРубКонечныйОстаток  as  СуммаРубКонОст
   |From  $РегистрОстаткиОбороты.Покупатели((Договор.НачПер), :ВыбКонПериода~,,,,,
   |                                 (Договор),(СуммаРуб)) as Рег
   |inner join (
   |Select $Дог.ГлубинаКредита ГлКредита,
   |    Дог.ID Догов,
   |    DATEADD(day,-$Дог.ГлубинаКредита,:ВыбКонПериода) НачПер,
   |    :ВыбКонПериода Сегодня
   |from
   |$Справочник.Договоры As Дог
   |) Договор on Договор.Догов = Рег.Договор
   |";
1 Андрей_Андреич
 
naïve
03.07.13
11:01
Получить остатки на конец периода и дополнить выборкой из движений и уже в этом запросе делать JOIN с договорами и фильтр на дату?
2 ADirks
 
03.07.13
11:02
Не выйдет. Виртуальные таблицы разворачиваются в реальные запросы на этапе компиляции - именно поэтому там требуется константное выражение.
Если есть сильно большое желание упихать всё в один запрос, то придётся всё делать ручками. Но, подозреваю, заметно лучше не станет.
3 Lacoster
 
03.07.13
11:06
Мне движения нужны. там остатки и обороты. А обороты я беру из начала периода и конца периода. Вся соль в том что туда нужно засунуть строку. Convert пробовал, но чё-то не понимает он это. Да и перед тем как Convert применить нужно дату развернуть годом вперед. Так что всё реально. но как дату в строку передалть ума не хватает
4 FoundMarket
 
03.07.13
11:07
еще один пытается восьмерошными запросами рулить в семерке :)
5 Андрей_Андреич
 
naïve
03.07.13
11:08
(2) Так в (1) через вирт.таблицу только остатки на конец периода. Не пойдет?
Ну или остатки на конец периода + в цикле параметризованный запрос?
6 Lacoster
 
03.07.13
11:11
мы скоро на 8 перейдем. Привыкаю.
А раньше так и было. Кицлом просто подставлялась дата в нужном формате и все. А тут я хочу все сразу и быстро, без циклов
7 ADirks
 
03.07.13
11:11
(3) если нужны обороты - так и обращайся к реальной таблице $Регистр.Покупатели с соотв. фильтром
8 Lacoster
 
03.07.13
11:16
(7) разве будет лучше обращаться так, чем к виртуальной? В виртуально-то уже что-то посчитано
9 Андрей_Андреич
 
naïve
03.07.13
11:24
(7) А такая конструкция допустима?
Select $Регистр.Покупатели.СуммаРуб СуммаРуб, Покупатели.DebKred ПриходРасход, $Регистр.Покупатели.Договор Договор
From $Регистр.Покупатели Покупатели
Inner Join $Справочник.Договоры Договоры On $Регистр.Покупатели.Договор = Договоры.Id
Where Left(Покупатели.DATE_TIME_IDDOC,8) > (и вот тут воткнуть конструкцию, вычитающую из кондаты глубину договора и приводящую ее к строке в виде ГГГГММДД)
10 Mikeware
 
03.07.13
11:31
(9) да. а зачем инер джойн тебе?
11 ADirks
 
03.07.13
11:32
(8) А без разницы. Тем более, что там ничего не посчитано.

вот, примерно так:


select
   Договоры.ID,
   Договоры.ДатаПоставки,
   регДв.СуммаПриход
from
   спрДоговоры Договоры

LEFT JOIN (
   SELECT
       рег.Договор,
       рег.Date_Time_IDDoc,
       Sum(рег.ДолгПриход) СуммаПриход,
       Sum(рег.ДолгРасход) СуммаРасход
   FROM
       регРасчетыСПокупателями рег
   WHERE
       (1=1) --рег.Date_Time_IDDoc > convert(char(8), Договоры.ДатаПоставки, 112)
       AND рег.Date_Time_IDDoc < '2013'--:КонДатаПлюс1
   GROUP BY
       рег.Договор, рег.Date_Time_IDDoc
   ) регДв ON
       регДВ.Договор = Договоры.ID
       AND регДв.Date_Time_IDDoc > convert(char(8), Договоры.ДатаПоставки, 112)

WHERE
   Договоры.ДатаПоставки > '17530101'


GROUP BY рег.Договор, рег.Date_Time_IDDoc
Выглядит конечно ужасно, но план запроса вполне ничего
12 Mikeware
 
03.07.13
11:32
(8) ничего там не подсчитано. она на то и "виртуальная", что ее нету :-)
13 Lacoster
 
03.07.13
11:34
(9) может и получится. Я просто не могу преобразовать в строку дату. А вот (11)  идею подкинул, щас посмотрю
14 Андрей_Андреич
 
naïve
03.07.13
11:34
(10) Я в запросах туплю. Раз надо сравнить с глубиной договора - надо соединять со справочником договоров. Или я тупей, чем думаю?
15 Mikeware
 
03.07.13
11:36
(14) а, ну тогда да, надо джойнить...
16 ADirks
 
03.07.13
12:00
прям интересно стало...
вот такой запрос

select
   Договоры.ID,
   Договоры.ДатаПоставки,
   Sum(рег.ДолгПриход) СуммаПриход,
   Sum(рег.ДолгРасход) СуммаРасход
from
   спрДоговоры Договоры

   LEFT JOIN регОплатаЗаявок рег ON
       рег.Договор = Договоры.ID
       AND рег.Date_Time_IDDoc > convert(char(8), Договоры.ДатаПоставки, 112)
       AND рег.Date_Time_IDDoc < '2013'--:КонДатаПлюс1

WHERE
   Договоры.ДатаПоставки > '17530101'
   AND рег.Договор Is Not Null
GROUP BY
   Договоры.ID,
   Договоры.ДатаПоставки
   
теоретически лучше предыдущего, но SQL генерит похожие планы, и время выполнения примерно одинаково.
17 Андрей_Андреич
 
naïve
03.07.13
12:10
(16) Так в справочнике договоров есть глубина кредита в днях (число). И надо отобрать движения с датой >= КонДатаОтчета - Договор.ГлубинаКредита, приведенной к строке ГГГГММДД.
Собственно, в (9) не хватает этой функции, ну и группировок.
Как это написать? В 1С 7.7 это выглядит как
Формат(Число(ДатаКонца)-Договор.ГлубинаКредита,"DГГГГММДД");
18 Lacoster
 
03.07.13
12:11
(16) а зачем ты делаешь лефт джоин после чего вхере? Можно и иннером обойтись
19 Lacoster
 
03.07.13
12:12
мужики, вот запрос
|Select
   |Рег.Договор [Договор $Справочник.Договоры],
   |    Рег.СуммаРубНачальныйОстаток as  СуммаРубНачОст,
   |    Рег.СуммаРубПриход          as  СуммаРубПриход,
   |    Рег.СуммаРубРасход          as  СуммаРубРасход,
   |    Рег.СуммаРубКонечныйОстаток  as  СуммаРубКонОст
   |From  $РегистрОстаткиОбороты.Покупатели((Договор.НачПер), :ВыбКонПериода~,,,,,
   |                                 (Договор),(СуммаРуб)) as Рег
   |inner join (
   |Select $Дог.ГлубинаКредита ГлКредита,
   |    Дог.ID Догов,
   |    Convert(char(8),DATEADD(day,-$Дог.ГлубинаКредита,:ВыбКонПериода),112) НачПер,
   |    :ВыбКонПериода Сегодня
   |from
   |$Справочник.Договоры As Дог
   |) Договор on Договор.Догов = Рег.Договор
   |";


Тип даты стал строкой и в нужном виде. Но он ругается теперь на $РегистрОстаткиОбороты.Покупатели((Договор.НачПер),.... перевый параметр
20 Mikeware
 
03.07.13
12:15
Ну тебе ж объяснили в (2)
21 ADirks
 
03.07.13
12:15
(17) DATEADD(day,-$Дог.ГлубинаКредита,:ВыбКонПериода)  (см. (1))

(18) ну это уже зависит от потребностей. AND рег.Договор Is Not Null  - это у меня осталось от экспериментов
22 Андрей_Андреич
 
naïve
03.07.13
12:15
(19) Забудь эту конструкцию (в данном случае). Уже говорили, что в качестве начала периода нужен конкретный параметр
23 Андрей_Андреич
 
naïve
03.07.13
12:18
(21) + Convert( Char(8), DateAdd(.....))?
Или DATEADD уже строку вернет?
24 ADirks
 
03.07.13
12:19
(23) ну если совсем полностью, то

Convert(char(8), DATEADD(day, -$Дог.ГлубинаКредита, :ВыбКонПериода), 112)

Весь вопрос, откуда брать начальную дату отсчета. У ТС это :ВыбКонПериода - константа, но обычно это дата кредитного документа, что делает жизнь сильно интереснее.
25 Андрей_Андреич
 
naïve
03.07.13
12:23
(24) Это уже как ТС босс сказал - так он и напишет. Скажет потом, что имел в виду другое - ТС перепишет. Ну а тут вопросик был про запрос :)