Имя: Пароль:
1C
1C 7.7
v7: Прямой запрос. Реквизиты регистра
0 1snik_d
 
28.05.19
10:36
Всем привет. Возникла необходимость получить значение реквизита регистра остатков в прямом запросе с виртуальными таблицами.
    |SELECT
    |      Выборка.Фирма as [Фирма $Справочник.Фирмы]
    |    , Выборка.МОЛ as [МОЛ $Справочник.ФизЛица]
    |    , Выборка.Номенклатура as [Номенклатура $Справочник.Номенклатура]
    |    , Выборка.Партия as [Партия $Справочник.Партии]
    |    , Выборка.ЦенаПрод
    |    , Выборка.СерияНоменклатуры as [СерияНоменклатуры $Справочник.СерииНоменклатуры]
    |    , RIGHT(Выборка.ПозицияДокумента,9) as [Документ $Документ]
    |    , Выборка.ВидДокумента as Документ_вид
    |    , Выборка.НомерСтрокиДокумента as НомерСтрокиДокумента
    |    , Выборка.ИтогПоФирма as ИтогПоФирма
    |    , Выборка.ИтогПоМОЛ as ИтогПоМОЛ
    |    , Выборка.ИтогПоНоменклатура as ИтогПоНоменклатура
    |    , Выборка.ИтогПоПартия as ИтогПоПартия
    |    , Выборка.ИтогПоЦенаПрод as ИтогПоЦенаПрод
    |    , Выборка.ИтогПоСерияНоменклатуры as ИтогПоСерияНоменклатуры
    |    , Выборка.ИтогПоПозицияДокумента as ИтогПоПозицияДокумента
    |    , Выборка.КоличествоНачальныйОстаток as КоличествоНачальныйОстаток
    |    , Выборка.КоличествоПриход as КоличествоПриход
    |    , Выборка.КоличествоРасход as КоличествоРасход
    |    , Выборка.КоличествоКонечныйОстаток as КоличествоКонечныйОстаток
    |    , Выборка.СуммаРубНачальныйОстаток as СуммаРубНачальныйОстаток
    |    , Выборка.СуммаРубПриход as СуммаРубПриход
    |    , Выборка.СуммаРубРасход as СуммаРубРасход
    |    , Выборка.СуммаРубКонечныйОстаток as СуммаРубКонечныйОстаток
    |    , Выборка.ПродСтоимость as ПродСтоимостьСумма
    |FROM
    |(
    |SELECT
    |      ПартииНаличиеОстаткиОбороты.Фирма as Фирма
    |    , ПартииНаличиеОстаткиОбороты.МОЛ as МОЛ
    |    , ПартииНаличиеОстаткиОбороты.Номенклатура as Номенклатура
    |    , ПартииНаличиеОстаткиОбороты.Партия as Партия
    |    , ПартииНаличиеОстаткиОбороты.ЦенаПрод as ЦенаПрод
    |    , ПартииНаличиеОстаткиОбороты.СерияНоменклатуры as СерияНоменклатуры
    |    , ПартииНаличиеОстаткиОбороты.ПозицияДокумента as ПозицияДокумента
    |    , GROUPING(ПартииНаличиеОстаткиОбороты.Фирма) as ИтогПоФирма
    |    , GROUPING(ПартииНаличиеОстаткиОбороты.МОЛ) as ИтогПоМОЛ
    |    , GROUPING(ПартииНаличиеОстаткиОбороты.Номенклатура) as ИтогПоНоменклатура
    |    , GROUPING(ПартииНаличиеОстаткиОбороты.Партия) as ИтогПоПартия
    |    , GROUPING(ПартииНаличиеОстаткиОбороты.ЦенаПрод) as ИтогПоЦенаПрод
    |    , GROUPING(ПартииНаличиеОстаткиОбороты.СерияНоменклатуры) as ИтогПоСерияНоменклатуры
    |    , GROUPING(ПартииНаличиеОстаткиОбороты.ПозицияДокумента) as ИтогПоПозицияДокумента
    |    , MAX(ПартииНаличие.LINENO_) as НомерСтрокиДокумента
    |    , MAX(ПартииНаличиеОстаткиОбороты.ВидДокумента) as ВидДокумента
    |    , Sum(ПартииНаличиеОстаткиОбороты.КоличествоНачальныйОстаток) as КоличествоНачальныйОстаток
    |    , Sum(ПартииНаличиеОстаткиОбороты.КоличествоПриход) as КоличествоПриход
    |    , Sum(ПартииНаличиеОстаткиОбороты.КоличествоРасход) as КоличествоРасход
    |    , Sum(ПартииНаличиеОстаткиОбороты.КоличествоКонечныйОстаток) as КоличествоКонечныйОстаток
    |    , Sum(ПартииНаличиеОстаткиОбороты.СуммаРубНачальныйОстаток) as СуммаРубНачальныйОстаток
    |    , Sum(ПартииНаличиеОстаткиОбороты.СуммаРубПриход) as СуммаРубПриход
    |    , Sum(ПартииНаличиеОстаткиОбороты.СуммаРубРасход) as СуммаРубРасход
    |    , Sum(ПартииНаличиеОстаткиОбороты.СуммаРубКонечныйОстаток) as СуммаРубКонечныйОстаток
    |    , Sum($ПартииНаличие.ПродСтоимость) as ПродСтоимость
    |FROM
    |    $РегистрОстаткиОбороты.ПартииНаличие(:НачДата, :КонДата~, Документ,,,
    |        (МОЛ = :ВыбМОЛ AND Номенклатура = :ВыбНоменклатура AND СтатусПартии <> $Перечисление.СтатусыПартии.Продукция AND СтатусПартии <> $Перечисление.СтатусыПартии.Услуга),
    |        (Фирма, МОЛ, Номенклатура, Партия, ЦенаПрод, СерияНоменклатуры),
    |        (Количество, СуммаРуб)) as ПартииНаличиеОстаткиОбороты
    |INNER JOIN $Регистр.ПартииНаличие as ПартииНаличие ON ПартииНаличиеОстаткиОбороты.Фирма = $ПартииНаличие.Фирма
    |                                                       AND ПартииНаличиеОстаткиОбороты.МОЛ = $ПартииНаличие.МОЛ
    |                                                       AND ПартииНаличиеОстаткиОбороты.Номенклатура = $ПартииНаличие.Номенклатура
    |                                                       AND ПартииНаличиеОстаткиОбороты.Партия = $ПартииНаличие.Партия
    |                                                       AND ПартииНаличиеОстаткиОбороты.ЦенаПрод = $ПартииНаличие.ЦенаПрод
    |                                                       AND ПартииНаличиеОстаткиОбороты.СерияНоменклатуры = $ПартииНаличие.СерияНоменклатуры
    |                                                       AND ПартииНаличиеОстаткиОбороты.ПозицияДокумента = ПартииНаличие.DATE_TIME_IDDOC
    |GROUP BY
    |    ПартииНаличиеОстаткиОбороты.Фирма
    |    , ПартииНаличиеОстаткиОбороты.МОЛ
    |    , ПартииНаличиеОстаткиОбороты.Номенклатура
    |    , ПартииНаличиеОстаткиОбороты.Партия
    |    , ПартииНаличиеОстаткиОбороты.ЦенаПрод
    |    , ПартииНаличиеОстаткиОбороты.СерияНоменклатуры
    |    , ПартииНаличиеОстаткиОбороты.ПозицияДокумента WITH ROLLUP
    |) as Выборка
    |ORDER BY
    |    Выборка.ИтогПоФирма DESC, Выборка.ИтогПоМОЛ DESC, Выборка.ИтогПоНоменклатура DESC, Выборка.ИтогПоПартия DESC, Выборка.ИтогПоЦенаПрод DESC, Выборка.ИтогПоСерияНоменклатуры DESC, Выборка.ИтогПоПозицияДокумента DESC";

Не могу придумать, как правильно соединиться с движениями регистра. Получаются дубли, если в документе есть одинаковые строчки.
1 1snik_d
 
28.05.19
10:40
И вообще - как корректнее соединяться с движениями регистра для получения значений реквизита, может я огород нагородил.
2 Mikeware
 
28.05.19
11:01
а зачем виртуальные таблицы-то?
3 dk
 
28.05.19
11:06
(2) +1
зачем  городить если можно из физ таббицы движений получить все и ничего ни с чем не соединять?
4 dk
 
28.05.19
11:07
таки консоль запросов развращает народ - думать надо чутка хотя бы
5 trad
 
28.05.19
11:29
|SELECT
|       ПартииНаличиеОстаткиОбороты.Фирма as [Фирма $Справочник.Фирмы]
|     , ПартииНаличиеОстаткиОбороты.МОЛ as [МОЛ $Справочник.ФизЛица]
|     , ПартииНаличиеОстаткиОбороты.Номенклатура as [Номенклатура $Справочник.Номенклатура]
|     , ПартииНаличиеОстаткиОбороты.Партия as [Партия $Справочник.Партии]
|     , ПартииНаличиеОстаткиОбороты.ЦенаПрод as ЦенаПрод
|     , ПартииНаличиеОстаткиОбороты.СерияНоменклатуры as [СерияНоменклатуры $Справочник.СерииНоменклатуры]
|     , RIGHT(ПартииНаличиеОстаткиОбороты.ПозицияДокумента,9) as [Документ $Документ]
|     , MAX(ПартииНаличиеОстаткиОбороты.ВидДокумента) as Документ_вид
|     , MAX(Движения.НомерСтрокиДокумента) as НомерСтрокиДокумента
|    
|     , GROUPING(ПартииНаличиеОстаткиОбороты.Фирма) as ИтогПоФирма
|     , GROUPING(ПартииНаличиеОстаткиОбороты.МОЛ) as ИтогПоМОЛ
|     , GROUPING(ПартииНаличиеОстаткиОбороты.Номенклатура) as ИтогПоНоменклатура
|     , GROUPING(ПартииНаличиеОстаткиОбороты.Партия) as ИтогПоПартия
|     , GROUPING(ПартииНаличиеОстаткиОбороты.ЦенаПрод) as ИтогПоЦенаПрод
|     , GROUPING(ПартииНаличиеОстаткиОбороты.СерияНоменклатуры) as ИтогПоСерияНоменклатуры
|     , GROUPING(ПартииНаличиеОстаткиОбороты.ПозицияДокумента) as ИтогПоПозицияДокумента
|    
|     , Sum(ПартииНаличиеОстаткиОбороты.КоличествоНачальныйОстаток) as КоличествоНачальныйОстаток
|     , Sum(ПартииНаличиеОстаткиОбороты.КоличествоПриход) as КоличествоПриход
|     , Sum(ПартииНаличиеОстаткиОбороты.КоличествоРасход) as КоличествоРасход
|     , Sum(ПартииНаличиеОстаткиОбороты.КоличествоКонечныйОстаток) as КоличествоКонечныйОстаток
|     , Sum(ПартииНаличиеОстаткиОбороты.СуммаРубНачальныйОстаток) as СуммаРубНачальныйОстаток
|     , Sum(ПартииНаличиеОстаткиОбороты.СуммаРубПриход) as СуммаРубПриход
|     , Sum(ПартииНаличиеОстаткиОбороты.СуммаРубРасход) as СуммаРубРасход
|     , Sum(ПартииНаличиеОстаткиОбороты.СуммаРубКонечныйОстаток) as СуммаРубКонечныйОстаток
|     , MAX(Движения.ПродСтоимость) as ПродСтоимостьСумма
|FROM
|    $РегистрОстаткиОбороты.ПартииНаличие(:НачДата, :КонДата~, Документ,,,
|        (МОЛ = :ВыбМОЛ AND Номенклатура = :ВыбНоменклатура AND СтатусПартии <> $Перечисление.СтатусыПартии.Продукция AND СтатусПартии <> $Перечисление.СтатусыПартии.Услуга),
|        (Фирма, МОЛ, Номенклатура, Партия, ЦенаПрод, СерияНоменклатуры),
|        (Количество, СуммаРуб)) as ПартииНаличиеОстаткиОбороты
|
|LEFT JOIN (
|    select
|        $ПартииНаличие.Фирма Фирма,
|        $ПартииНаличие.МОЛ МОЛ,
|        $ПартииНаличие.Номенклатура Номенклатура,
|        $ПартииНаличие.Партия Партия,
|        $ПартииНаличие.ЦенаПрод ЦенаПрод,
|        $ПартииНаличие.СерияНоменклатуры СерияНоменклатуры,
|        ПартииНаличие.DATE_TIME_IDDOC ПозицияДокумента,
|        Sum($ПартииНаличие.ПродСтоимость) as ПродСтоимость,
|        MAX(ПартииНаличие.LINENO_) as НомерСтрокиДокумента
|    from $Регистр.ПартииНаличие as ПартииНаличие
|    group by
|        $ПартииНаличие.Фирма,
|        $ПартииНаличие.МОЛ,
|        $ПартииНаличие.Номенклатура,
|        $ПартииНаличие.Партия,
|        $ПартииНаличие.ЦенаПрод,
|        $ПартииНаличие.СерияНоменклатуры,
|        ПартииНаличие.DATE_TIME_IDDOC
|) Движения
|    ON ПартииНаличиеОстаткиОбороты.Фирма = Движения.Фирма
|  AND ПартииНаличиеОстаткиОбороты.МОЛ = Движения.МОЛ
|  AND ПартииНаличиеОстаткиОбороты.Номенклатура = Движения.Номенклатура
|  AND ПартииНаличиеОстаткиОбороты.Партия = Движения.Партия
|  AND ПартииНаличиеОстаткиОбороты.ЦенаПрод = Движения.ЦенаПрод
|  AND ПартииНаличиеОстаткиОбороты.СерияНоменклатуры = Движения.СерияНоменклатуры
|  AND ПартииНаличиеОстаткиОбороты.ПозицияДокумента = Движения.ПозицияДокумента
|
|
|GROUP BY
|    ПартииНаличиеОстаткиОбороты.Фирма
|    , ПартииНаличиеОстаткиОбороты.МОЛ
|    , ПартииНаличиеОстаткиОбороты.Номенклатура
|    , ПартииНаличиеОстаткиОбороты.Партия
|    , ПартииНаличиеОстаткиОбороты.ЦенаПрод
|    , ПартииНаличиеОстаткиОбороты.СерияНоменклатуры
|    , ПартииНаличиеОстаткиОбороты.ПозицияДокумента WITH ROLLUP
|ORDER BY
|    GROUPING(ПартииНаличиеОстаткиОбороты.Фирма) DESC,
|    GROUPING(ПартииНаличиеОстаткиОбороты.МОЛ) DESC,
|    GROUPING(ПартииНаличиеОстаткиОбороты.Номенклатура) DESC,
|    GROUPING(ПартииНаличиеОстаткиОбороты.Партия) DESC,
|    GROUPING(ПартииНаличиеОстаткиОбороты.ЦенаПрод) DESC,
|    GROUPING(ПартииНаличиеОстаткиОбороты.СерияНоменклатуры) DESC,
|    GROUPING(ПартииНаличиеОстаткиОбороты.ПозицияДокумента) DESC
6 1snik_d
 
28.05.19
12:28
(3) Так остатки нужны, а их проще из виртуальных таблиц брать
7 1snik_d
 
28.05.19
12:33
(6) И приход-расход
8 1snik_d
 
28.05.19
12:34
(3) Не проще, запрос сложнее будет
9 dk
 
28.05.19
12:35
остатки
UNION
движения
10 1snik_d
 
28.05.19
12:37
(9) Несколько UNION (отдельно для прихода, отдельно для расхода)
11 1snik_d
 
28.05.19
12:53
(5) Запрос рабочий, но насколько он оптимален, вот вопрос
12 trad
 
28.05.19
13:00
(11) получи и проанализируй план выполнено и ответишь на свой вопрос
13 trad
 
28.05.19
13:01
*план выполнения
14 1snik_d
 
28.05.19
13:25
(13) Большую часть времени сортировка заняла, так что запрос нормальный получился
15 1snik_d
 
28.05.19
13:26
(13) Левое соединение вообще практически не потребляет ресурсы.
16 1snik_d
 
28.05.19
13:33
1с++ еще и временные таблицы создает - круть какая ))
17 1snik_d
 
28.05.19
13:36
А для восьмерки есть что-то подобное, чтобы напрямую в SQL ломится в обход сервера приложений?
18 1snik_d
 
28.05.19
13:36
*ломиться
19 Mikeware
 
28.05.19
13:37
(17) лицензией запрещено
20 Mikeware
 
28.05.19
13:38
+(19) а вообще, есть получение структуры хранения, ну а там уж сам ломись и крути как хочешь...
только зачем?
в клющках-то это от безысходности было.... черные запросы навевали черную тоску...
21 1snik_d
 
28.05.19
13:43
(20) Да я бы и черным запросом обошелся, если бы он зараза в 2ГБ временного dbf файла умещался. Работал-то он приемлемо по скорости.
22 Mikeware
 
28.05.19
14:05
(21) всегда можно поиграть периодами
23 trad
 
28.05.19
15:30
(15) все дело в том, что условие соединения, как минимум это:
AND ПартииНаличиеОстаткиОбороты.ПозицияДокумента = Движения.ПозицияДокумента
- уходит "внутрь" подзапроса и приводит к использованию индекса и к хорошей селективности.

А если есть быстрые движение по ресурсу, например по Номенклатуре, то будет использован индекс по Номенклатура+Позиция, что еще селективнее.

ps
Но, что бы планировщик запроса не уходил в блуд, нужно MAXDOP = 1