Имя: Пароль:
1C
1C 7.7
v7: 1Sqlite Левое соединение по документу неопределенного вида
0 Aleksey
 
27.09.16
05:20
Есть Документ заявка. На основании его вводиться реализация (связь через реквизит ДокОсновании с типом Документ).

Нужно вывести все заявки на основании которых еще небыло выписано реализаций

И во тут у меня небольшой ступор, как сделать связь если реквизит хранит вид документа и его IDD

Select
ДокЗ.IDDOC [ДокумЗаказ :Документ.Заявка]
ДокР.IDDOC [ДокумРеализация :Документ.Реализация]

from [Документ_Заявка] as ДокЗ
Left Join Документ_Реализация as ДокР ON ДокР.ДокОснование =
???? (ДокЗ.IDDOC)
1 Это_mike
 
27.09.16
07:09
ДокР.ДокОснование = $ВидДокумента36.Заявка+(ДокЗ.IDDOC)

Или  right(ДокР.ДокОснование,9) = (ДокЗ.IDDOC)
2 orefkov
 
27.09.16
08:23
(1)
Для sqlite лучше первый вариант.
А лучше бы через таблицу подчинённых документов, 1crdoc вроде бы.
3 Это_mike
 
27.09.16
08:35
(2) так вроде второй лучше в индекс попадает? по иддок?
ну и можно через подчиненные - 1scrdoc, но не быстрее вроде - придется кроме подчинения фильтровать по виду, а это соединение с журналом.
пробовать - лениво.
4 Aleksey
 
27.09.16
09:24
Что такое $ВидДокумента36? В хелпе описано :ВидДокумента (через двоеточие и без цифр). А так ругается, говорит нет такой колонки.

Пробовал и :ВидДокумента.Заявка+(ДокЗ.IDDOC), не ругается, но и ничего не находит.

Но меня смущает что запрос вида
Select :ВидДокумента.Заявка+(ДокЗ.IDDOC)from [Документ_Заявка]  
возвращает число, а не конкатенацию строк, т.е.

Select IDDOC, :ВидДокумента.Заявка, :ВидДокумента.Заявка+(ДокЗ.IDDOC)
возвращает таблицу со строками

5AX4U | PPC | 5
5AX4V | PPC | 5
5AX4W | PPC | 5
5 Это_mike
 
27.09.16
09:27
(4) ВидДокумента / DocumentKind
Подстановка идентификатора указанного вида документа:

:ВидДокумента|DocumentKind.ИмяДокумента[~]

При нулевом модификаторе подставляется строка длиной 4 символа - идентификатор вида документа в 36ричной записи

При модификаторе 1 подставляется целое число - идентификатор вида документа.
6 Это_mike
 
27.09.16
09:29
+(5) накрайняк есть  id2str(ИД, чДлинаСтроки)
7 orefkov
 
27.09.16
09:34
В sqlite для конкатенации строк используется не '+', а '||'
то есть
ДокР.ДокОснование = $ВидДокумента36.Заявка || (ДокЗ.IDDOC)
8 Это_mike
 
27.09.16
09:39
(7) хм. сюрпрайз...
да, для общего развития - а что сделает "+" ?
9 orefkov
 
27.09.16
09:39
Во, для sqlite условие будет такое:
ДокЗ.IDDOC = substr(ДокР.ДокОснование, 5, 9)
10 orefkov
 
27.09.16
09:40
(8)
Арифметическое сложение
11 orefkov
 
27.09.16
09:51
Даже так
ДокЗ.IDDOC = substr(ДокР.ДокОснование, -9)
12 Aleksey
 
27.09.16
10:06
(7) пробовал и так - не находит, т.е. в селекте показывает правильно а в условиях не находит
P.S.  $ВидДокумента36 - так что это такое? Это случайно не из 1Срр и класса прямой запрос?
13 orefkov
 
27.09.16
10:20
для 1sqlite надо писать просто
:ВидДокумента
14 orefkov
 
27.09.16
10:21
+(13) Дико извиняюсь, давно с 1sqlite не работал, навскидку не помню, пришлось в доку лезть :)
15 Это_mike
 
27.09.16
10:21
(12) я ж тебе в (5) процитировал...
16 Aleksey
 
27.09.16
10:29
(15) Да я уточнить, может у меня длл старая и есть какойто новый секретный релиз, где такой синтаксис

Ну все равно не находит хоть ты тресни

Делаю тупо запрос по документам реализации, с условием
where ДокОснование = :ВидДокумента.Заявка||' 5AX4V'
запрос возвращает документ


А изначальный запрос
хоть
ON substr(ДокР.ДокОснование, -9) = ДокЗ.IDDOC,
хоть
ON ДокР.ДокОснование = :ВидДокумента.Заявка||ДокЗ.IDDOC

не находит реализации, хоть ты тресни
17 Ёпрст
 
гуру
27.09.16
10:44
(16) покажи полный текст запроса
18 orefkov
 
27.09.16
10:47
О, посмотрел внимательно.
Тебе надо ко всем заявкам цеплять реализации лефт-джойном?
Такое надо делать только через 1scrdoc, ибо по ДокР.ДокОснование индекса нет, тормозить будет чудовищно.
Желательно даже графу отбора сделать для этого.
19 Aleksey
 
27.09.16
10:47
(18) Мне тупо надо найти те заявки по которым еще небыло реализаций
20 Aleksey
 
27.09.16
10:52
(17) А это и есть практически полный.

В полной версии там просто названия документов другие

Есть регистр - ТпЗ_ТоварПодЗаказ, который двигает одноименный документ - ТпЗ_ТоварПодЗаказ.
На основании этого документа вводиться документ - ДокументСделка через реквизит ДокОснование.

Соответственно нужно найти те документы ТпЗ_ТоварПодЗаказ, по которым еще нет документа ДокументСделка.

Пока что на первом этапе хочу получить табличку вида
ТоварПодЗаказ | Сделка

Select
Рег.IDDOC [ТоварПодЗаказ :Документ.ТпЗ_ТоварПодЗаказ],
Сделка.IDDOC as [ДокумСделка :Документ.ДокументСделка]

from [Регистр.ТпЗ_ТоварПодЗаказ] as Рег
Left Join Документ_ДокументСделка  as Сделка ON Сделка.ДокОснование =
:ВидДокумента.ТпЗ_ТоварПодЗаказ||Рег.IDDOC
21 Aleksey
 
27.09.16
10:55
(18) В 1scrdoc я так и не понял как определить вид в CHILDID, ID же будут совпадать у документов разного вида
22 Это_mike
 
27.09.16
10:57
(21) джойнить с журналом.
или, как сказано в (18), графу отбора
23 orefkov
 
27.09.16
10:57
(21)
docid уникальные вообще, не пересекаются у доков разных видов.
24 Ёпрст
 
гуру
27.09.16
11:27
(20) на основании ТпЗ_ТоварПодЗаказ вводится только 1 вид документа ?
Если да, то так

Select

Рег.IDDOC [ТоварПодЗаказ :Документ.ТпЗ_ТоварПодЗаказ],
from [Регистр.ТпЗ_ТоварПодЗаказ] as Рег
where Рег.IDDOC not in
(select substr(ParentVal, 7, 9) from __1SCRDOC where mdid=0)
25 Ёпрст
 
гуру
27.09.16
11:29
Select
Рег.IDDOC [ТоварПодЗаказ :Документ.ТпЗ_ТоварПодЗаказ],
from [Регистр.ТпЗ_ТоварПодЗаказ] as Рег
where Рег.IDDOC not in
(select substr(ParentVal, 7, 9) from _1С.CRDOC where mdid=0)
26 Ёпрст
 
гуру
27.09.16
11:30
так точнее, если я правильно помню, как таблички с 1s**** подключаются
27 Злопчинский
 
27.09.16
11:36
А не надо ли сначала посмотреть те товары под заказ которые не закрыты сделками, и только по оставшимся незакрытым колдыбанить дальше?
28 Aleksey
 
27.09.16
11:45
(24) Много, еще 3. сам документ, закрытие и заказ
29 Aleksey
 
27.09.16
11:50
(27) Нет, там все сложнее. В этом документе как товар под заказ, так и товар с нашего основного склада. Дальше он распадается на документ сделка (это то что лежит на складе и будет отгружаться непосредственно со склада) и документ заказ поставщику товара под заказ - это то что нет на нашем складе, но есть у поставщика.

Вот как раз чтобы они не забыли отгрузить с основного склада и ваяю отчет, который покажет, что забыли.
А для этого я тупо делаю нулевое движение в регистре с определенным значением реквизита.
Ну а далее через отбор по движению, где мой реквизит = 1 получаю список документов по которым нужно проверить подчиненость
30 Злопчинский
 
27.09.16
11:57
(29)  на вкус и цвет
Мну такая концепция не нравится
Есть товары под заказ в регистре,
То что можно отгрузить - ставим в резерв, что нельзя отгрузить болтается в регистре без резерва
Соответственно что в резерве стоит то или можно отгрузить или забыли отгрузить - рулится типа плановой датой отгрузки
31 Djelf
 
гуру
27.09.16
11:59
Ну вот как то так...

SELECT
    Заявка.IDDOC [Заявка $Документ.ЗаявкаПокупателя]
FROM Журнал AS ж
LEFT JOIN Документ_ЗаявкаПокупателя as Заявка ON ж.IDDOC=Заявка.IDDOC

LEFT JOIN (
SELECT
    Заявка.IDDOC Заявка
    ,Ссылки.CHILDID Реализация
FROM Журнал AS ж
LEFT JOIN Документ_ЗаявкаПокупателя as Заявка ON ж.IDDOC=Заявка.IDDOC
LEFT JOIN __1S_CRDOC AS Ссылки
    ON  Ссылки.MDID='   0'
    AND Ссылки.PARENTVAL='O1'||:ВидДокумента.ЗаявкаПокупателя||Заявка.IDDOC
INNER JOIN Документ_Реализация as Реализация ON Реализация.IDDOC= Ссылки.CHILDID
WHERE ж.IDDOCDEF=:ВидДокумента.ЗаявкаПокупателя
    AND ж.date BETWEEN :НачДата AND :КонДата
) AS ЗаявкиРеализации ON ЗаявкиРеализации.Заявка=Заявка.IDDOC

WHERE ж.IDDOCDEF=:ВидДокумента.ЗаявкаПокупателя
    AND ж.date BETWEEN :НачДата AND :КонДата
    AND ЗаявкиРеализации.Заявка IS NULL

Правда на оригинальной 1.0.2.6/3.7.10 это около 5с
На 1.0.2.6/3.14.1 150мс ;)
32 Злопчинский
 
27.09.16
11:59
У мну по такой схеме как ты-я описал работало долго и успешно на базе тис, у главного отгрузчика весел арм, где показывалось сколько позиций заказано, сколько можно отгрузить полностью, сколько частично
И вообщем все
33 Aleksey
 
27.09.16
12:00
(30) На текущим этапе можно и так. Просто отгрузка со склада старый, отладенный блок, поэтому пока его хотел оставить как есть. А блок товара под заказ еще пока в творческом процесск, постоянно меняются документы и регистры
34 Aleksey
 
27.09.16
12:56
(32) У меня просто сделка потягивает новый товар в резерв. Т.е. она ставит товар который есть на складе. Если пришел еще товар, вводим на основании и она забирает в резерв новый товар.
А товар под заказ - это товар под заказ (т.е. жесткий резерв), заказали, привезли, отгрузили. Т.е. тут нет варианта, а вдруг откуда та придёт этот товар. Он либо есть у поставщика и мы его отгрузили, либо поставщик делает отказ и мы отказываем клиенту

Т.е. у них разные возможности и назначения, поэтому и хотелось бы чтобы они так и жили отдельно, но при этом есть желания дать менеджеру принимать заказ в одном месте, т.е. чтобы он в мог принять заказ как по товару под заказ, так и с основного склада, не прыгая по документам.
35 Djelf
 
гуру
27.09.16
12:59
Финальный вариант, с NOT IN - 135мс на всех версиях 1sqlite

-- Запрос ЗаявокПокупателя по которым не выписаны Реализации
SELECT
    Заявка.IDDOC [Заявка $Документ.ЗаявкаПокупателя]
FROM Журнал AS ж
LEFT JOIN Документ_ЗаявкаПокупателя as Заявка ON ж.IDDOC=Заявка.IDDOC
WHERE ж.IDDOCDEF=:ВидДокумента.ЗаявкаПокупателя
    AND ж.date BETWEEN :НачДата AND :КонДата
    AND Заявка.IDDOC NOT IN
(
SELECT
    Заявка.IDDOC
FROM Журнал AS ж
LEFT JOIN Документ_ЗаявкаПокупателя as Заявка ON ж.IDDOC=Заявка.IDDOC
LEFT JOIN __1S_CRDOC AS Ссылки
    ON  Ссылки.MDID='   0'
    AND Ссылки.PARENTVAL='O1'||:ВидДокумента.ЗаявкаПокупателя||Заявка.IDDOC
INNER JOIN Документ_Реализация as Реализация ON Реализация.IDDOC= Ссылки.CHILDID
WHERE ж.IDDOCDEF=:ВидДокумента.ЗаявкаПокупателя
    AND ж.date BETWEEN :НачДата AND :КонДата
)
36 Aleksey
 
27.09.16
19:04
(35) Спасибо большое.
В принципе ограничения по дате мне не нужно, поэтому убрал у себя запрос к журналу, добавил недостающие индексы и вроде даже что то похожее на правду показывает
37 Злопчинский
 
27.09.16
19:55
(35)  это хорошо
Но больше интересно концептуально: за счёт чего?
38 Djelf
 
гуру
27.09.16
20:47
(37) Хорошо! Разбираем по косточкам ;)

Первая выборка от которой плящем
ж.IDDOCDEF=:ВидДокумента.ЗаявкаПокупателя AND ж.date BETWEEN :НачДата AND :КонДата
Попадаем в индекс DOCTYPE = IDDOCDEF,DATE,TIME,IDDOC    
объем полученных данных из журнала минимальный, и скорость уже не увеличить!

Дальше клеим ссылки по __1S_CRDOC, тут главное Ссылки.MDID='   0'  иначе индекс использоваться не будет!
А строка
AND Ссылки.PARENTVAL = 'O1'||:ВидДокумента.ЗаявкаПокупателя||Заявка.IDDOC
дополняет попадание в длинный индекс
PARENT  = MDID,PARENTVAL,CHILDDATE,CHILDTIME,CHILDID    

вот это INNER JOIN Документ_Реализация нужно для отсеивания только реализаций, т.к. у меня еще есть ссылки в Развозке и они будут мешаться

Фактически мы везде попадаем в индекс и попадаем в правильный план (последовательность перебора таблиц).
Идеальнее наверное некуда...

Отличие по скорости 5с/135мс на движке sqlite 3.7.10 между запросами это оптимизатор с планом дурит...
А вот у sqlite 3.14.1 план тоже разный, но есть и автоиндексы на выбранные данные, это вытягивает первый вариант запроса до скорости второго.
39 Djelf
 
гуру
27.09.16
20:59
+(38) Вот это Ссылки.PARENTVAL = 'O1' мне не нравится...
Думаю подпилить типизацию sqlite т.е. сейчас есть
:ВидДокумента.ЗаявкаПокупателя который подставляет ид4 документа
Тут несколько вариантов
1. подстановка :Документ без точки после, чтобы оно 'O1' выводило - не нравится...
2. модификатор к :ВидДокумента.ЗаявкаПокупателя, чтобы оно 'O1' приклеивало спереди, это уже нравится
3. подстановка :ТипЗначения.Документ, вместо 1, вроде ничего... в дополнении к 2 будет не плохо.
40 Djelf
 
гуру
27.09.16
21:05
(36) Ты с датой это... без фанатизма!
Смысл при текущей работе искать мертвые заявки 1967г?
Ну ладно, не 67й, но если заявка за 3 месяца не завершена, то скорее всего совсем протухла.
137мс это за месяц, если отрубить 10с у меня получается, но зачем?
41 Aleksey
 
27.09.16
22:58
(40) Некретично. Мы заявки раз в 2 недели удаляем, иначе база начинает дико тупить (хз почему, ну если к примеру пару месяцев не чистить отчет который смотрит движения товара и резервы (планирование закупок начинает работать на 2 порядка медленее (именно порядка)), стоит удалить движения или когда их мало всё хорошо). Так что если будем считать что выборка физически ограничена максимум 2-3 недели, так что никакого фанатизма, всё под контролем
42 Djelf
 
гуру
27.09.16
23:51
(41) Это твоя база и твои правила ;)