|   |   | 
| 
 | Как правильно составить условие запроса? | ☑ | ||
|---|---|---|---|---|
| 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) Да - не увидел.     | 
 
 | Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |