|
v7: SQL запрос к двум Таблицам Значений | ☑ | ||
---|---|---|---|---|
0
evgpinsk_
29.05.21
✎
22:55
|
Есть две таблицы значений.
Хотел бы через SQL запрос сделать выборку из эти двух таблиц. примерно так: SELECT Товары.Код, Товары.Наименование FROM Разделы INNER JOIN Товары ON Разделы.Код = Товары.Код; Сейчас я обе ТЗ через базаДанных.уложитьТЗ() укладываю в виртуальную таблицу. А дальше мне эти таблицы нужно объеденить в запросе и получить выборку. Это реально? |
|||
1
ДенисЧ
30.05.21
✎
04:03
|
А почему нет, если у тебя есть две таблицы, имена которых ты знаешь?
|
|||
2
acanta
30.05.21
✎
06:17
|
А что "уложитьТЗ" делает с именами полей?
|
|||
3
evgpinsk_
30.05.21
✎
08:38
|
(1) Не нашёл в гугле как
(2) Не понял вопрос. Ничего не делает, просто создаёт в памяти таблицу, к которой можно обращаться через SQLiteBase базаДанных.уложитьТЗ(ИсходнаяТЗ,"ПолучаемсяТаблицаДляSQL",0); и не нашёл что определяет 3й параметр |
|||
4
ДенисЧ
30.05.21
✎
08:44
|
базаДанных.уложитьТЗ(ИсходнаяТЗ,"ПолучаемсяТаблицаДляSQL1",0);
базаДанных.уложитьТЗ(ИсходнаяТЗ,"ПолучаемсяТаблицаДляSQL2",0); запрос = " |SELECT т1.*. т2.* FROM ПолучаемсяТаблицаДляSQL1 AS т1 |FULL JOIN ПолучаемсяТаблицаДляSQL2 AS т2 |ON TRUE "; |
|||
5
evgpinsk_
30.05.21
✎
10:05
|
(4) Спс
|
|||
6
Sserj
30.05.21
✎
11:23
|
(3)
Синтаксис: УложитьТЗ(ТЗ, ИмяТаблицы, [КакПостоянную]) Параметры: ТЗ - тип: ТаблицаЗначений. Таблица, загружаемая в базу данных ИмяТаблицы - тип: Строка. Имя создаваемой в базе данных таблицы. КакПостоянную - тип: Число. 1 - создать обычную таблицу, 0 - создать временную таблицу. Необязательный параметр. По умолчанию 0. Возвращает: нет Описание: Загружает таблицу значений в базу данных, как таблицу базы данных. Если таблица с указанным именем уже существует, она удаляется. Состав полей созданной таблицы соответствует составу колонок ТЗ. Имена полей созданной таблицы соответствуют идентификаторам колонок ТЗ. Формат в котором выгружаются значения из ТЗ, см в Преобразование значений 1С в значения базы данных (работа с параметрами) |
|||
7
evgpinsk_
30.05.21
✎
13:41
|
Последний затык остался, на пути решения общей задачи
Есть две таблицы: ХарактеристикиТМЦ три поля (ТМЦ, Характеристика, ЗначениеХарактеристики as Значение) - все характеристики всех товаров и ГруппыТМЦ и три поля (ГруппаТМЦ, Характеристика, ЗначениеХарактеристики as Значение) - на Группы товаров мы можем задать характеристики. Задача - определить для Товара, в какую Группу его нужно перенести. Условие что Значения всех введённые характеристик Группы товаров равны Значениям этих же характеристик у товара. Ниже скрин ситуации: https://prnt.sc/13l62xz Через SQL запрос решается данная задача? /я так понимаю он не совсем тривиальный/ Либо проще эту задачу решать через ТаблицыЗначений и циклы к ним? |
|||
8
Garykom
гуру
30.05.21
✎
13:54
|
(0) На 77 обычно быстрее ТЗ без sql запросов обрабатывать
Так что вперед с циклами, только правильными Не надо удалять или изменять записи в текущих ТЗ, создай новую добавляй строки в неё |
|||
9
evgpinsk_
30.05.21
✎
14:11
|
(8) Сначала показалось, что запрос простой будет и потратил часов 5 на доизучение SQLiteBase.
И на последнем шаге затык ) А с циклами через ТЗ - тоже думаю подумать над алгоритмом придётся |
|||
10
Djelf
30.05.21
✎
14:34
|
(7) Не понятно зачем сначала запихивать все это в тз, сразу к таблицам прицепится нельзя что-ли?
Ничего не понял из твоего описания ;) (8) Да, 7ка хорошо работает с циклами на тз, только с итз все все равно быстрее будет, а с 1sqlite ни то, ни другое не нужно! |
|||
11
evgpinsk_
30.05.21
✎
14:41
|
(10) >Не понятно зачем сначала запихивать все это в тз, сразу к таблицам прицепится нельзя что-ли?
Я запихивал в ТЗ для наглядности отладки. Пj факту через SQlite я сразу обращаюсь к справочникам. И сделал 85% всех движений. Предполагал что последний запрос будет лёгким. А по факту он не тривиален |
|||
12
Djelf
30.05.21
✎
14:55
|
(11) А вот так делать не надо!
sqlite это встраивая база данных, она никогда не сможет ни кэшировать гигабайты в оперативке, ни выполнять огромное количество совершенно ненужной работы... Тем более что это все прилеплено к 1С 7.7 и статистики никакой нет и не будет. Принцип эффективной работы на 1sqlite такой: - сначала выбираем таблицу у которой получится с условием в where наименьшее количество записей (проверяем в консоли, получилось? ок, идем дальше). - left join`ом клеим вторую, третью, четвертую таблицу. (проверяем последовательно). - inner join использовать не стоит (нет статистики, только предположения, а они очень не точные). Лучше отфильтровать полученные данные после left join в where (в 90% случаев это быстрее). И (8) Прав, только сказал по другому, тут фактически получается тот же перебор тз, но на более эффективном движке. |
|||
13
evgpinsk_
30.05.21
✎
15:08
|
(12) Не совсем понял что не верно.
Тут вопрос не в скорости , а в том как решить задачу ). Мне показалось что решение будет простым через SQL запросы. Поэтому и пошёл этим путём Через: запрос.ВыполнитьЗапрос("create virtual table ХарактеристикиГрупп using dbeng(Справочник.ХарактеристикиГрупп)"); запрос.ВыполнитьЗапрос("create virtual table Товары using dbeng(Справочник.ТМЦ)"); читаю нужные мне справочники в память, и дальше через SQL запросы думал получить нужный результат |
|||
14
Djelf
30.05.21
✎
15:15
|
(13) create virtual table не нужно - читай документацию, там 2 варианта автоподключения таблиц 1С есть.
SQL работает не так! Тебе не надо все тащить из базы... Только необходимое! И одним запросом в 1sqlite это должно работать. Путь действий я в (12) написал. |
|||
15
evgpinsk_
30.05.21
✎
15:17
|
(14) > create virtual table не нужно - читай документацию
если бы ещё иметь эту документацию ) |
|||
16
Djelf
30.05.21
✎
15:25
|
(15) Скачай уже... https://snegopat.ru/1sqlite/index Ой! Нету ;)
Но ты отважный, парень! Без документации это... ххх... Забирай: https://cloud.mail.ru/public/aceG/K247Dds3o |
|||
17
Garykom
гуру
30.05.21
✎
15:33
|
(12) >но на более эффективном движке
а время на передачу данных и назад? |
|||
18
Djelf
30.05.21
✎
15:35
|
(17) Это время ничтожно. Это не 8ка с ее NativeAPI, все через память передается.
|
|||
19
evgpinsk_
30.05.21
✎
15:36
|
Но ведь /как мне казалось/ 1с и их ТЗ не имеют мощный функционал выборки данных через Select.
Там только циклы |
|||
20
trdm
30.05.21
✎
15:38
|
(16) Сам chm-ку делал?
|
|||
21
Djelf
30.05.21
✎
15:40
|
(20) Спер! Честно, спер! У Орефкова... Но копирайты там все есть...
|
|||
22
trdm
30.05.21
✎
15:43
|
(21) Нет, я к тому что до сих пор не разобрался как вот эти элементы в нее пихать:
https://prnt.sc/13lb6hg красным обвел. Моя скомпилированная справа. |
|||
23
Djelf
30.05.21
✎
16:57
|
(22) Прости, я не помню откуда у меня эта chm, экспериментировал с ними, но эта точно не от туда...
|
|||
24
evgpinsk_
30.05.21
✎
19:47
|
Есть ли возможность в 1sqlite работать с составными запросами? т.е. описать сначала один простой запрос
и потом во втором запросе обратится к нему как к таблице. п.с. (16) по ссылке chm не открывает содержимое разделов: https://prnt.sc/13ljllr |
|||
25
Злопчинский
30.05.21
✎
20:49
|
вычитать и складывать тз можно через 1с++ итз
|
|||
26
evgpinsk_
30.05.21
✎
20:54
|
(24) > Есть ли возможность в 1sqlite работать с составными запросами? т.е. описать сначала один простой запрос
и потом во втором запросе обратится к нему как к таблице. Отвечаю сам себе, нашёл такой способ решения /хотя не нравится он мне/: Результат=Запрос.ВыполнитьЗапрос(ТекстЗапроса); Результат.выгрузить(ТЗ1с); базаДанных.уложитьТЗ(ТЗ1с,"с1",0); Выполняю запрос, затем выгружаю его в таблицу значений, а затем эту таблицу значений укладываю в новую таблицу. Правильно или есть другой способ? |
|||
27
evgpinsk_
30.05.21
✎
21:18
|
Поздравляю сам себя, решил задачу через SQL запросы.
Теперь при оприходовании товара импортом из екселя все новые товары падают изначально в нужную группу 1го уровня. Затем парсятся характеристики товаров. И затем на основании этих характеристик они разносятся по правильным подгруппам многоуровнего справочника номенклатуры. На скрине ниже каждая ТЗ - это промежуточный какойто результат https://prnt.sc/13lmj8c |
|||
28
Злопчинский
30.05.21
✎
21:42
|
Молодец, возьми с полки пирожок! ;-)
|
|||
29
Sserj
31.05.21
✎
03:11
|
(26) 1sqlite умеет CTE:
with НужноеИмя as ( select спр.id as Элемент , спр.descr as Наименование from Справочник_Номенклатура as спр ) select товары.Элемент as [Товар $Справочник.Номенклатура] , товары.Наименование as [Наименование $Строка] .... from НужноеИмя as товары join .... on товары.Элемент = .... |
|||
30
DrZombi
гуру
31.05.21
✎
06:15
|
(0) Реально.
|
|||
31
Mikeware
31.05.21
✎
07:40
|
(0) открой для себя https://www.1cpp.ru/docum/html/IndexedTable.html#innerjoin
|
|||
32
evgpinsk_
31.05.21
✎
09:37
|
(29) Да, то что в одном запросе можно использовать подзапросы, это понятно. Но так сложнее писать.
Проще когда создал подзапрос, увидел его отработку, и потом обращаешься к нему из другого запроса. Пример из Access: SELECT Таблица1.Поле1, Таблица1.Поле2 FROM Таблица1; (Этот запрос сохранён под именем Запрос) SELECT Запрос.Поле1 FROM Запрос GROUP BY Запрос.Поле1; |
|||
33
Djelf
31.05.21
✎
10:11
|
(32) Сделай вьюшку и обращайся к ней https://sqlite.org/lang_createview.html Будет то же самое.
|
|||
34
Mikeware
31.05.21
✎
10:41
|
(33) ты, конечно, учишь хорошему. Но как в анекдоте про попа и бизнесмена "но зря".
у чувака _уже_ есть ТЗ, ему надо их обработать. зачем выгружатьв бд-вычислять-загружать из бд, если эти же действия можно сделать сразу над ТЗ? (ну по меньшей мере, джойны и группировки) |
|||
35
evgpinsk_
31.05.21
✎
10:48
|
(34) Мне казалось, что есть задачи, которые через SQL легче решаются чем через циклы в ТЗ
|
|||
36
Mikeware
31.05.21
✎
11:03
|
(35) а кто сказал про циклы?
не, SQL тоже преобразует все в циклы (можно посмотреть в плане исполнения запроса), но мы ж не об этом... ты (31) пробовал прочитать? ну и там то, что рядом? (Правое..., Левое..., Полное...) |
|||
37
Salimbek
31.05.21
✎
11:19
|
Голосую за Индексированную таблицу! С индексами, фильтрами, поиском по нескольким полям и прочими плюшками...
|
|||
38
Mikeware
31.05.21
✎
11:46
|
(37) как минимум в данном случае...
ну а вообще - "каждому овощу свой фрухт!"©, т.е. любой инструмент уместен в своем случае... |
|||
39
evgpinsk_
31.05.21
✎
12:04
|
(36) увидел по ссылке иннерджоин и подумал что там про sql. Про итз узнал только сейчас
|
|||
40
Злопчинский
31.05.21
✎
12:54
|
(39) юзай, очень удобно и быстро
|
|||
41
evgpinsk_
31.05.21
✎
13:14
|
(33) Здесь не догоняю. Может есть пример, как сохранить запрос, чтобы потом к нему обращаться по имени?
|
|||
42
Djelf
31.05.21
✎
13:31
|
(41) Легко!
Только навсегда запомни - типизация из внутреннего представления, в данном случае [Товар :Справочник.Номенклатура] должна быть только тогда, когда (верхний) запрос возвращает данные в тз или итз, или в ТабличноеПоле. Все внутренние запросы, в том числе и все VIEW должны быть без типизации! |
|||
43
Mikeware
31.05.21
✎
13:40
|
(42) он же без типизации результат "в читаемом виде" не увидит... :-) а ему именно для этого надо...
в принципе, пофиг... 100500 вариантов ему дали, пущай кувыркаиццо.... |
|||
44
Djelf
31.05.21
✎
13:42
|
(37) Я интенсивно использовал ИТЗ, до тех пока не изучил 1sqlite ;)
Кое-где все равно ИТЗ использую. Когда в таблицу нужно добавить через* вычисляемую колонку и по ней отфильтровать. Напрягает что ИТЗ нельзя выгрузить в таблицу sqlite! Приходится прогонять через ТЗ. Могу сделать эту выгрузку, но не понятно как попроще преобразовывать не типизированные значений ИТЗ в сокращенные/типизированные в sqlite ;( |
|||
45
Djelf
31.05.21
✎
13:44
|
(43) Ты забыл уже наверное! Он при внутренней типизации все значения перекорёжит и поубивает! Т.е. этот вопрос все равно возникнет ;)
|
|||
46
Злопчинский
31.05.21
✎
13:55
|
(44) "Когда в таблицу нужно добавить через* вычисляемую колонку "
- это как? |
|||
47
Djelf
31.05.21
✎
14:05
|
(46) Ну, это такая гадость бывает, которую очередной креативный менеджер захотел, а как оформить как оно работает забыл!
Типа вычисления Торгового по каждому документу, когда Торгового нет в ПКО, или их там два или три, эксклюзивных, не эксклюзивных и паразитирующих. Ну... я не всегда прав, но из-за придурка, который мне всю базу, при нормальном подходе, переломает под свои фантазии, а потом свалит через пару месяцев... Пускай тратит на это свое время, а не мое ;) |
|||
48
Mikeware
31.05.21
✎
15:36
|
(45) не, я-то помню, когда надо типизировать, и когда не надо... собственно, поэтому и порекомендовал работать с ИТЗ - ему проще
(47) "паразитирующий ТП" - хорошее определение! |
|||
49
evgpinsk_
31.05.21
✎
22:39
|
(42) Застрял на VIEW
вот этот код отрабатывает хорошо: Текстзапрос="DROP VIEW IF EXISTS ТЗГруппыТМЦ_2"; тз=запрос.ВыполнитьЗапрос(Текстзапрос); Представление= " |CREATE VIEW temp.ТЗГруппыТМЦ_2 AS SELECT Count(ТЗГруппыТМЦ_.Хар) AS Колич, ТЗГруппыТМЦ_.ГруппаУр1 as [ГруппаУр1_ $Справочник.ТМЦ], ТЗГруппыТМЦ_.Группа as [Группа $Справочник.ТМЦ] |FROM ТЗГруппыТМЦ_ |GROUP BY ТЗГруппыТМЦ_.ГруппаУр1, ТЗГруппыТМЦ_.Группа;"; Текстзапрос="Select * from ТЗГруппыТМЦ_2;"; // Вот в этой строке если ставим * то всё ок тз=запрос.ВыполнитьЗапрос(Текстзапрос); тз.Выгрузить(ТЗРез); результат: https://prnt.sc/13n6vqd Но я не пойму, как напрямую обратиться к полям VIEW /к тем, которые справочники/, выбивает на любых вариантах ошибку: Текстзапрос="Select Колич from ТЗГруппыТМЦ_2;"; - РАБОТАЕТ Текстзапрос="Select ГруппаУр1_ from ТЗГруппыТМЦ_2;"; - ошибка "no such column: ГруппаУр1_" Текстзапрос="Select ТЗГруппыТМЦ_2.ГруппаУр1_ from ТЗГруппыТМЦ_2;"; - ошибка "no such column: ГруппаУр1_" Текстзапрос="Select ГруппаУр1_ [ГруппаУр1_ :Справочник.ТМЦ] from ТЗГруппыТМЦ_2;"; - ошибка "no such column: ГруппаУр1_" Текстзапрос="Select ГруппаУр1_ [ГруппаУр1_ &Справочник.ТМЦ] from ТЗГруппыТМЦ_2;"; - ошибка "no such column: ГруппаУр1_" |
|||
50
Salimbek
31.05.21
✎
23:38
|
(49) Вот это вот: "ТЗГруппыТМЦ_.ГруппаУр1 as [ГруппаУр1_ $Справочник.ТМЦ]" - это именно то, что тебе прямо запрещали делать в (42)
Правильно так: "ТЗГруппыТМЦ_.ГруппаУр1 as ГруппаУр1_" Дело в том, что в квадратных скобках - это имя столбца (если в ней есть пробел или другие спец.символы, если ничего такого нет, то можно и без квадратных, как у меня выше). И поэтому в первом случае у тебя создается колонка с именем "ГруппаУр1_ $Справочник.ТМЦ". И именно поэтому у тебя запрос ругается, что нет такой колонки "ГруппаУр1_". А далее - когда 1С-ка получает данные из запроса, то компонента находит такое дурацкое имя колонки (с наличием " $Справочник.ТМЦ"), понимает, что тут ты хочешь получить данные из этого Справочника и производит подмену. При этом она сама отрезает в имени колонки лишнее. И поэтому в итоге мы видим уже правильное имя колонки "ГруппаУр1_" в которой лежат элементы этого справочника. |
|||
51
evgpinsk_
31.05.21
✎
23:57
|
(50) > Правильно так: "ТЗГруппыТМЦ_.ГруппаУр1 as ГруппаУр1_"
Да, прошло. Просто странно, почему в моём варианте вьюшки запрос вида: Текстзапрос="Select * from ТЗГруппыТМЦ_2;"; - Работает. (в (49) виден скрин результата) И раз он работает, то я предполагала что в запросе както можно обратиться напрямую к его полям, а не только через * |
|||
52
Mikeware
01.06.21
✎
06:25
|
(45) Ну вот, я ж говорил в (48)...
|
|||
53
evgpinsk_
01.06.21
✎
08:23
|
(52) просто не понятно почему select * работало
|
|||
54
Mikeware
01.06.21
✎
08:58
|
(53) понятно. Но объяснять не буду. Используй работу с ИТЗ
|
|||
55
Arbuz
01.06.21
✎
15:15
|
(50) Ну вот. Я использовал это (название колонки с типизацией) как какую-то магию, а ты взял и все кишки популярно объяснил. (:
|
|||
56
Djelf
01.06.21
✎
15:47
|
(53) Ну отлично же (50) все написал! Понятнее объяснить это было бы сложно.
Выполни запрос SELECT name FROM pragma_table_info('ТЗГруппыТМЦ_2'); Для обоих вариантах создания представления, и (53) должно стать понятно... |
|||
57
Mikeware
01.06.21
✎
15:53
|
(56) <тут должен быть анекдот про негра и молоко>
|
|||
58
Djelf
01.06.21
✎
16:01
|
+(56) Но если нужно и так и сяк делать запросы (т.е. использовать в других запросах и выборку по Полю и через Звездочку), то и это не проблема!
Но учти такую штуку: sqlite проталкивает условия в WHERE внешнего запроса представлению внутрь VIEW! Т.е. количество записей в таких запросах будет уменьшаться, а вот выкидывать из запроса лишние поля, к которым нет обращения (пока?) не умеет. Т.е. РасшифровкаТовара в финальной версии не нужна, это лишние колонки на больших объемах может вызвать замедление. (57) Да ладно тебе, во первых он писал что не программист, во вторых рисует в конструкторе Access. Может когда сам научится другим поможет... А упорство уже есть ;) |
|||
59
Mikeware
01.06.21
✎
16:05
|
(58) ну пределы некомпетентности тоже надо осознавать. я понимаю, что плох тот чайник, который не мечтает стать самоваром, но всё-таки...
|
|||
60
Djelf
01.06.21
✎
16:12
|
(59) Ну, в Необходим быстрый поиск информации в больших CSV файлах он заставил и меня мозгами поскрипеть ;)
|
|||
61
Salimbek
01.06.21
✎
16:44
|
(53) Дык, в чем проблема то?
Ты делаешь запрос "Выбрать все поля из таблицы". SQLite без проблем выполняет этот запрос, возвращает тебе ответ с колонкой с именем "ГруппаУр1_ $Справочник.ТМЦ", 1С-ка видит "волшебное поле", радостно хлопает в ладошки, применяет свою магию и ты получаешь в ответ табличку с полем "ГруппаУр1_" и содержимым внутри "Справочник.ТМЦ" |
|||
62
Djelf
01.06.21
✎
19:40
|
(61) У него проблема в последовательных запросах к VIEW. т.е. хочется и звездочкой получить всю таблицу для отладки и просмотра, и одновременно использовать поле в коротком представлении, без типизации. Решается запросом в (58).
|
|||
63
evgpinsk_
02.06.21
✎
09:23
|
(59) Одно дело, когда всю жизнь заниматься программированием, и совсем другое когда учитель вьетнамского тебе 5й раз раз объясняет чем один тон отличается от другого (посмотрел бы я на тебя на скорость изучения данного языка и компетентность). Также и с синтаксисом SQL в 1с - в инете Хелпа толкового нет, приходится писать наугд.
|
|||
64
evgpinsk_
02.06.21
✎
09:33
|
(61) > Дык, в чем проблема то?
) неужели не понятно, почему у новичка случился в данном случае затык ?? Очень ведь легко: Бал запрос первый - это VIEW и был запрос второй, "Select * from View;" Который выполнялся и возвращал результат со всеми колонками. Естественно я предполагал что первый VIEW запрос написан верно, раз он обрабатывался. И естесвенно что я искал ошибку во второй запросе, когда вместо * пытался обратится к полям первого запроса напрямую. П.с. одно дело, когда на эту проблему смотрит или носитель языка или практикующий несколько лет, и совсем другое - когда ктото с опытом в несколько дней |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |