|
Как правильно составить условие запроса? | ☑ | ||
---|---|---|---|---|
0
МешочекЗнаний
13.08.21
✎
14:04
|
Приветствую уважаемые.
Безбожно туплю на запросе. Упрощённый пример: У характеристики номенклатуры имеются дополнительные реквизиты (Длина, Ширина, Высота, Цвет). -------------------------------- - Длина - Ширина - Высота - Цвет - 1 - 2 - 3 - Серый - 1 - 2 - 4 - Серый - 2 - 2 - 3 - Серый -------------------------------- Мне например нужно выбрать характеристику с длиной = 1; шириной = 2; высотой = 4; Цвет - Серый. Не могу понять как правильно составить запрос чтобы правильно получить данные. Попробовал так: [spoiler] |ГДЕ | (ХарактеристикиНоменклатурыДополнительныеРеквизиты.Свойство = &ДлинаСвойство | И ХарактеристикиНоменклатурыДополнительныеРеквизиты.Значение = &ДлинаЗначение | И ХарактеристикиНоменклатурыДополнительныеРеквизиты.Свойство = &ШиринаСвойство | И ХарактеристикиНоменклатурыДополнительныеРеквизиты.Значение = &ШиринаЗначение | И ХарактеристикиНоменклатурыДополнительныеРеквизиты.Свойство = &ТолщинаСвойство | И ХарактеристикиНоменклатурыДополнительныеРеквизиты.Значение = &ТолщинаЗначение) [/spoiler] Но запрос ничего не возвращает, это логично т.к. на одно и то же поле (свойство) накладывается взаимоисключающие непересекающиеся условие Попробовал так: [spoiler] |ГДЕ | (ХарактеристикиНоменклатурыДополнительныеРеквизиты.Свойство, ХарактеристикиНоменклатурыДополнительныеРеквизиты.Значение) В (&ТЗ_СвойстваИЗначения) [/spoiler] Запрос возвращает все данные, где встречается хоть одна комбинация из доп реквизитов. В принципе могу решить проблему и наговнокодить типо такого (Пошагово отсекать лишние данные), но по-моему это плохой вариант. [spoiler] "ВЫБРАТЬ | ХарактеристикиНоменклатурыДополнительныеРеквизиты.Ссылка КАК Ссылка |ПОМЕСТИТЬ ВТ_ОтборПоДлине |ИЗ | Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты КАК ХарактеристикиНоменклатурыДополнительныеРеквизиты |ГДЕ | ХарактеристикиНоменклатурыДополнительныеРеквизиты.Свойство = &ДлинаСвойство | И ХарактеристикиНоменклатурыДополнительныеРеквизиты.Значение = &ДлинаЗначение |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | ХарактеристикиНоменклатурыДополнительныеРеквизиты.Ссылка КАК Ссылка |ПОМЕСТИТЬ ВТ_ОтборПоШирине |ИЗ | Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты КАК ХарактеристикиНоменклатурыДополнительныеРеквизиты |ГДЕ | ХарактеристикиНоменклатурыДополнительныеРеквизиты.Свойство = &ШиринаСвойство | И ХарактеристикиНоменклатурыДополнительныеРеквизиты.Значение = &ШиринаЗначение | И ХарактеристикиНоменклатурыДополнительныеРеквизиты.Ссылка В | (ВЫБРАТЬ | ВТ_ОтборПоДлине.Ссылка | ИЗ | ВТ_ОтборПоДлине)... [/spoiler] Прошу помочь мыслями, как сделать по правильному. |
|||
1
Волшебник
модератор
13.08.21
✎
14:08
|
на каждое свойство нужно отдельное левое соединение и отдельное поле
|
|||
2
Said_We
13.08.21
✎
14:37
|
(0) Не нужны левые соединения....
Запрос по характеристикам |
|||
3
Said_We
13.08.21
✎
14:59
|
(0) В твоем случае необходимо найти все номенклатуры, у которых заданные свойства одновременно.
1) Свойство1 = Значение1 ИЛИ Свойство2 = Значение2 ИЛИ Свойство3 = Значение3 ИЛИ Свойство4 = Значение4 2) Полученную таблицу разворачиваешь и сворачиваешь как в ссылке (2) через Макс(Выбрать Когда...конец) 3) Накладываешь условие одновременное Свойство1 = Значение1 И Свойство2 = Значение2 И Свойство3 = Значение3 И Свойство4 = Значение4 Нет тут никаких левых соединений и т.д. |
|||
4
Said_We
13.08.21
✎
15:06
|
(0) Суть я понятно расписал?
|
|||
5
Kassern
13.08.21
✎
15:09
|
(3) Чет зачастили эти темы с характеристиками в последнее время)
|
|||
6
Said_We
13.08.21
✎
15:12
|
(5) Есть такое. Сам удивляюсь.
Я не знаю почему эти характеристики постоянно хотят получать левыми соединениями и постоянно отдельно по каждому свойству отдельно. В типовых примерно так же упорно делают через левое соединение - это страшно медленно работает. Зачем - не знаю. |
|||
7
Kassern
13.08.21
✎
15:30
|
(6) чтобы не потерять данные из основной таблицы видимо.
|
|||
8
Said_We
13.08.21
✎
15:33
|
(7) Если необходимо получить набор свойств для списка номенклатуры, то это дополнительное объединение с пустыми свойствами.
Это как раз задача из ссылки в (2). Опять же нет там соединения. |
|||
9
Said_We
13.08.21
✎
15:35
|
(7) По ссылке в (2) пост 28. Нет потерь никаких. Пояснения есть :-)
|
|||
10
RomanYS
13.08.21
✎
15:55
|
(8) ни разу не понятно чем юнион с выбором и группировкой лучше вполне естественных для данной задачи соединений. Ну и в (0) задача несколько отличается от (2), здесь даже левые соединения не нужны - с внутренними должно быть быстрее
|
|||
11
Said_We
13.08.21
✎
16:05
|
(10) "ем юнион с выбором и группировкой лучше " - быстрее.
|
|||
12
Said_We
13.08.21
✎
18:29
|
(10) "вполне естественных для данной задачи соединений" - не соглашусь, там где можно обойтись без JOIN там они не естественны.
|
|||
13
RomanYS
13.08.21
✎
22:18
|
(11) замеры покажешь?
(12) всегда считал группировки бОльшим злом чем джойн |
|||
14
sapphire
14.08.21
✎
00:58
|
(5) Понеже не умеют их готовить и сие самая захламленная таблица
|
|||
15
sapphire
14.08.21
✎
01:01
|
Еще хуже, если характеристики замножены, например, использованы доп свойства.
Нужно: 1) Типизировать владельца характеристики с отбором по наименованию 2) Отобрать выбранные в п 1 по заданному критерию |
|||
16
VS-1976
14.08.21
✎
01:25
|
Примерно можно сделать так. Суть набросал, а там если что подправишь
ВЫБРАТЬ Свойство, Значение ПОМЕСТИТЬ тзСвойстваОбъекта ИЗ &ТаблицаСвойствОбъекта КАК тзСвойстваОбъекта ; ВЫБРАТЬ тзДопРеквизиты.Ссылка КАК Характеристика ИЗ тзСвойстваОбъекта, ( ВЫБРАТЬ КОЛИЧЕСТВО( Свойство ) КАК КолСвойств ИЗ тзСвойстваОбъекта) КАК тзКоличество СОЕДИНЕНИЕ Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты КАК тзДопРеквизиты ПО тзДопРеквизиты.Свойство = тзСвойстваОбъекта.Свойство И тзДопРеквизиты.Значение = тзСвойстваОбъекта.Значение СГРУППИРОВАТЬ ПО тзДопРеквизиты.Ссылка ИМЕЮЩИЕ КОЛИЧЕСТВО( тзДопРеквизиты.Ссылка ) = тзКоличество.КолСвойств |
|||
17
VS-1976
14.08.21
✎
01:43
|
(16) Можно так же убрать соединение с количеством, передав количество параметром ( что бы поэкономить память )
ИМЕЮЩИЕ КОЛИЧЕСТВО( тзДопРеквизиты.Ссылка ) = &КолСвойств |
|||
18
МешочекЗнаний
14.08.21
✎
11:16
|
(4) Благодарю за ответ! Посидел, сделал похожий запрос на своих данных, получил требуемый результат. Красивое решение без использования соединений. Добавил способ в свой багаж знаний.
(10) Попробовал с внутренним соединением, получается наглядно и понятно. Скорее всего на этом способе остановлюсь т.к. и скорость работы хорошая, и после меня кто будет сопровождать легче будет разобрать запрос. (16) Спасибо за идею. Попробовал этот способ, но на моих данных запрос отрабатывает в 5 раз медленней чем в (4) или (10). |
|||
19
VS-1976
14.08.21
✎
19:40
|
(18) Можно в принципе убрать соединение ( не универсально но всё же ), попробуй, может так быстрее )
ВЫБРАТЬ Ссылка КАК Характеристика ИЗ Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты ГДЕ ( Свойство = &ДлинаСвойство И Значение = &ДлинаЗначение ) Или ( Свойство = &ДлинаСвойство И Значение = &ШиринаЗначение ) Или ( Свойство = &ТолщинаСвойство И Значение = &ТолщинаЗначение ) Или ( Свойство = &ЦветСвойство И Значение = &ЦветЗначение ) СГРУППИРОВАТЬ ПО Ссылка ИМЕЮЩИЕ КОЛИЧЕСТВО( Ссылка ) = 4 |
|||
20
VS-1976
14.08.21
✎
19:45
|
(19) Пречатка
Или ( Свойство = &ШиринаСвойство |
|||
21
VS-1976
14.08.21
✎
20:04
|
(19) Теоретически этот запрос можно написать так, что бы он работал ещё быстрее, при условии что "Значение" жутко составной тип и записей миллионы. Что бы не подымать много данных с диска, в начале можно определиться со свойствами. Свойства лежат отдельной индексной таблице и она не большая. Отобрать те характеристики, у которых все свойства есть ( заполнены ), а потом уже фильтровать по значениям но там уже будет соединение по индексу. Теоретически можно уменьшить I/O
|
|||
22
Said_We
15.08.21
✎
12:17
|
(13) В (18) замер производительности.
Если внимательно почитаешь ветку в (2), то там тоже есть замер производительности. На данных у автора получилось в 10 раз быстрее чем с джинами. Почему так - тоже расписано в ветке. Ещё раз здесь перефразирую пост 29 в (2) "JOIN - это убийца производительности запросов.". Так было всегда и 10 лет назад и 20 лет назад и 30 лет назад. Сейчас с наличием оконных функций можно максимально обходится без JOIN, .... но не в 1С. 1С уже отстали на 10 лет от всего мира в части SQL. Уже в 2018 году оконные функции появились в SQLLite, который пишет один человек, а огромный штат 1С не смог и не хочет. Выигрыш в производительности зачастую доходит до нескольких порядков. Проверял запросы на чистом SQL с использованием оконных функций и аналогичные по функционалу с JOIN. Это просто небо и земля. |
|||
23
Said_We
15.08.21
✎
12:26
|
(18) "Скорее всего на этом способе остановлюсь т.к. и скорость работы хорошая" - это пока у тебя задача найти все, у которых одновременно свойства такие-то.
А как только задача встанет, например: * Найти и показать вместе со свойствами все номенклатурные позиции у которых: одно из свойств, такое-то ИЛИ другое свойство такое-то ИЛИ... * Найти значение пяти свойств для перечня номенклатуры. То использовать Внутреннее Соединение уже не сможешь и будет не быстро :-) А решение в (2) универсальное и быстрое практически при любой постановки задачи про свойства. |
|||
24
RomanYS
15.08.21
✎
12:26
|
(22) только в (18) вывод обратный твоему
|
|||
25
Said_We
15.08.21
✎
12:32
|
(24) В (23) пояснения.
|
|||
26
Said_We
15.08.21
✎
12:44
|
(20) + всё в подзапрос и свернуть по "ВЫБРАТЬ т.Характеристика КАК Характеристика" или через выбрать различные или группировкой. Дабы по 4-ре раза одного и того же не было.
|
|||
27
Said_We
15.08.21
✎
12:55
|
(13) "всегда считал группировки бОльшим злом чем джойн" - просто так ТАК считал или замерял производительность?
|
|||
28
VS-1976
15.08.21
✎
14:54
|
(26) Не понял, а как по твоему будет 4-ре раза одного и того же? ). Если запись одна для одной характеристики и свойству, почему их должно быть четыре? 4-ре записи будет тогда, когда все условия выполнены. Группировка и так есть СГРУППИРОВАТЬ ПО Ссылка - по этому ссылка вернётся в единственном числе, а условие ИМЕЮЩИЕ КОЛИЧЕСТВО( Ссылка ) = 4 отфильтрует те группы, у которых условия не выполены, то есть не все 4 свойства заполныны или заполнено хотя бы одно значение из четырёх не тем значением.
|
|||
29
Said_We
15.08.21
✎
15:06
|
(28) Да - не увидел.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |