Имя: Пароль:
1C
1C 7.7
v7: Помогите с SQLiteBase как обработать join привести в единый формат
0 sysadminlk
 
22.04.20
21:45
текстЗапроса="SELECT Бланки.DESCR, Бланки.Документ, ДокСф.IDDOC FROM Бланки
    |LEFT JOIN ДокСф on Бланки.Документ = ДокСф.IDDoc
    |WHERE ДокСф.БланкНалоговой = :ПустойИД;";

    запрос.ВыполнитьЗапрос("create virtual table Бланки using dbeng(Справочник.БланкиСчетфактур)");
    запрос.ВыполнитьЗапрос("create virtual table ДокСф using dbeng(Документ.СчетФактураЛК)");    


Проблема что
Бланки.Документ имеет формат " 56D   1LS   "
ДокСф.IDDoc имеет формат "   1LS   "

Соответственно сравнение не получается (не работает ON)

Я думал как вариант добавить в таблицу новый столбец, но выдает virtual tables may not be altered

А как привести к одному формату данные ума не могу дать.

Подскажите люди добрые.
1 Злопчинский
 
22.04.20
22:53
а зачем в селекте
Бланки.Документ, ДокСф.IDDOC
если - как я понял - это одно и то же значение..?
2 Злопчинский
 
22.04.20
22:54
а, сорри, ступил
3 sysadminlk
 
23.04.20
12:52
не поверю что тут нет гуру по SQLiteBase
4 Djelf
 
гуру
23.04.20
13:22
(0) Обмани, пусть sqlite думает что это документ. :ВидДокумента.СчетФактураЛК||Бланки.Документ  = ДокСф.IDDoc
5 Djelf
 
гуру
23.04.20
13:23
А... сори, наоборот.
Бланки.Документ =  :ВидДокумента.СчетФактураЛК||ДокСф.IDDoc
или с помощью substr отрезать лишнее в Бланки.Документ
6 sysadminlk
 
23.04.20
13:57
(5) ООО сработало. Спасибо.

    запрос.Подставлять("ПустойИД", "     0   ");
    текстЗапроса="SELECT Бланки.DESCR, Бланки.Документ [ДокСпр :Документ], ДокСф.IDDOC [ДокДок :Документ.СчетФактураЛК] FROM Бланки
    |INNER JOIN ДокСф ON :ВидДокумента.СчетФактураЛК||ДокСф.IDDoc = Бланки.Документ
    |WHERE ДокСф.БланкНалоговой = :ПустойИД;";
    Сообщить(запрос.ОбработатьТекстЗапроса(текстЗапроса));
    тз=запрос.ВыполнитьЗапрос(текстЗапроса);


Сообщить выдало:

SELECT Бланки.DESCR, Бланки.Документ [ДокСпр :Документ], ДокСф.IDDOC [ДокДок :Документ.СчетФактураЛК] FROM Бланки
INNER JOIN ДокСф ON ' 56D'||ДокСф.IDDoc = Бланки.Документ
WHERE ДокСф.БланкНалоговой = '     0   ';

а я не знал что что соединяют через ||
я пробовал через + вот так: INNER JOIN ДокСф ON ' 56D  '+ДокСф.IDDoc = Бланки.Документ
вручную написал ' 56D  '
а надо было писать без двух пробелов в конце: ' 56D' и ставить вместо плюса надо было два пайпа
Как хорошо что есть люди которые могут подсказать. Еще раз спасибо. А то уже вторые сутки поиска идут )))
Спасибо, спасибо, спасибо!!!
7 orefkov
 
23.04.20
14:03
(5)
subsr лучше не надо - в индекс однозначно не попадёт.
(6)
В sqlite для операции конкатенации (соединения) строк используется ||, а + всегда складывает арифметически, т.е. приводит к числу и складывает два числа.
8 Djelf
 
гуру
23.04.20
14:18
(7) Как раз наоборот!
Первый проход по справочнику Бланки будет без индекса т.к. отбора нет.
Второй проход идет сравнением по iddoc документа, если написать :ВидДокумента.СчетФактураЛК||ДокСф.IDDoc, то индекс по iddoc использоваться не будет.
А вот если написать так ДокСф.IDDoc = substr(Бланки.Документ,5), то сравнение будет по индексу.
9 Djelf
 
гуру
23.04.20
14:26
+(8) Это потому что left join, был бы inner join хитрый sqlite поменял бы таблицы местами и  :ВидДокумента.СчетФактураЛК||ДокСф.IDDoc тоже было по индексу.
10 orefkov
 
23.04.20
16:36
(8), (9)
Ну, тут многое зависит от размеров этих таблиц, и наличия отбора по ДокСф.БланкНалоговой и сортировки по Бланки.Документ.
Если Бланки больше таблицы счетов-фактур, то оптимальнее пройти внешним циклом по таблице ДокСф, цепляя к ним Бланки.
Если же Бланки небольшая, то тогда лучше "join ... on ДокСф.IDDoc = substr(Бланки.Документ,5)" и в Where еще добавить "and substr(Бланки.Документ,1, 4) = :ВидДокумента.СчетФактураЛК"
А если ДокСф.БланкНалоговой в графах отбора есть, то лучше вообще через 1crdoc идти, сразу выцепить с пустым значением.
11 Djelf
 
гуру
23.04.20
16:52
(10) Да, отсюда не видать структуру таблиц и данных. Возможны варианты.
Но оптимизатор значительно сильнее сейчас стал.
Вот, например, запрос к аналогичному случаю, оптимизатор сработал идеально.
Но, в идеале, запрос должен быть составлен так, чтобы оптимизатор даже не пытался додумывать ;)


FROM Справочник_Ходки AS сХодки
INNER JOIN Документ_Ходка AS Ходка ON substr(Ходка.IDDOC,0) = сХодки.Ходка
Подбор индекса для таблицы SC34076 :
    Ограничения: SP34072[Ходка]=;
    Выбран индекс VI34072: SP34072
    Стоимость: 18
Подбор индекса для таблицы SC34076 :
    Ограничения:
    Индекс не выбран.
    Стоимость: 224739
Подбор индекса для таблицы DH28840 :
    Ограничения:
    Индекс не выбран.
    Стоимость: 20064

План использования таблиц                                                                                                                                                
selectid        order        from        detail                                                                                                                        
3        0        0        SCAN TABLE Документ_Ходка AS Ходка VIRTUAL TABLE INDEX -1:noIdx;     2                                                                                                                         
7        0        0        SCAN TABLE Справочник_Ходки AS сХодки VIRTUAL TABLE INDEX 1:VI34072;    10 !" 0p nHyd!