Имя: Пароль:
1C
1C 7.7
v7: Запрос для поиска номенклатуры
,
0 zenon46
 
11.12.23
16:52
Вопрос, чета не соображу никак, как сделать, в клюшках есть справочник свойства номенклатуры, с двумя реквизитами вид свойства и значение свойства, есть у меня две таблицы в одной условно - 3 вида свойства в другой таблице 3 значения, как-то можно запросом найти всю номенклатуры у которой будут эти 3 вида и 3 значения в соответствии.
Нарисовал такой запрос

SELECT
 СпрН.ID AS [Аналог $Справочник.Номенклатура]
FROM
 $Справочник.Номенклатура AS СпрН With (NOLOCK)
LEFT JOIN
 $Справочник.СвойстваНоменклатуры AS СпрСвойстваНоменкл With (NOLOCK) ON СпрСвойстваНоменкл.ParentExt = СпрН.ID
WHERE 
 $СпрСвойстваНоменкл.ВидСвойства IN (SELECT val FROM #TempTableSvojstva)
 AND $СпрСвойстваНоменкл.ЗначениеСвойства IN (SELECT val FROM #TempTableZnachen)


Конечно в результатах, ерунда. Но может кто подскажет, как вообще реализовать такую задачу, перебором конечно не есть хорошо, это будет до бесконечности долго.
1 Звездец
 
11.12.23
16:59
что-то запрос явно не из 7.7
2 zenon46
 
11.12.23
17:05
(1) прямиком из 7.7, это использование 1Cpp.dll
3 ilya_i
 
11.12.23
17:06
наверно INNER JOIN с $Справочник.СвойстваНоменклатуры и
INNER JOIN с таблицей из двух колонок аля ВидСвойства и ЗначениеСвойства
4 zenon46
 
11.12.23
17:12
(3) а умеет оно так с таблицей из двух колонок работать ?
5 Sserj
 
11.12.23
17:19
В этом запросе Справочник.Номенклатура вообще не нужен.
Только если потом поля его понадобятся а так:
SELECT
СпрСвойстваНоменкл.ParentExt AS [Аналог $Справочник.Номенклатура]
FROM
$Справочник.СвойстваНоменклатуры AS СпрСвойстваНоменкл With (NOLOCK)
WHERE
$СпрСвойстваНоменкл.ВидСвойства IN (SELECT val FROM #TempTableSvojstva)
AND $СпрСвойстваНоменкл.ЗначениеСвойства IN (SELECT val FROM #TempTableZnachen)
6 zenon46
 
11.12.23
17:26
(5) результат выборки ровно такой-же как и в моем запросе.
Не совсем корректный. Может я не совсем объяснил что нужно получить.
К примеру
Три свойства
А
Б
В
И три значения
1
2
3

Так вот получить нужно номенклатуру к которой будет в справочник "Свойства номенклатуры" вот такая комбинация
A 1
Б 2
В 3
7 AAA
 
11.12.23
19:32
Как вариант это UNION из трех подзапросов, в каждом из которых выбирается один вид свойства  с конкретным значением.
Можно их запихать в ТЗ и запрос построить из подзапроса автоматически. Можно сделать тоже самое с OR (ИЛИ), но я почему то не люблю его )
8 AAA
 
11.12.23
19:36
Можно сделать служебный справочник с реквизитами "ВидСвойства,ЗначениеСвойства". Его заполнять требуемыми значениями и использовать в запросе. Тогда не надо никаких UINION или OR
9 zenon46
 
11.12.23
19:36
(7) 3 это для примера, может быть и 2 и 5 и вообще сколько угодно.
10 AAA
 
11.12.23
19:44
(10)Делайте через служебный справочник, в него пишите хоть 100000 комбинаций
11 Sserj
 
11.12.23
19:54
(6) Мне не понятно взаимоотношений твоих двух виртуальных таблиц. Почему это именно две таблицы. Какое у них между собой отношение.
Может быть только А1, Б2, В3 или может быть и А1, А2, А3 и т.д...
В общем случае думаю должно быть что-то типа такого:

with всеУсловия as (
select
  t1.val as [Свойство]
  , t2.val as [Значение]
from
  #TempTableSvojstva as t1 cross join as t2
)

select
  СпрСвойстваНоменкл.ParentExt AS [Аналог $Справочник.Номенклатура]
from
  $Справочник.СвойстваНоменклатуры AS СпрСвойстваНоменкл With (NOLOCK)
  join всеУсловия on (
  $СпрСвойстваНоменкл.ВидСвойства = всеУсловия.Свойство
  and $СпрСвойстваНоменкл.ЗначениеСвойства = всеУсловия.Значение)
12 Sserj
 
11.12.23
19:56
+(11) Виртуальная недопечаталась:
with всеУсловия as (
select
  t1.val as [Свойство]
  , t2.val as [Значение]
from
  #TempTableSvojstva as t1
  cross join  #TempTableZnachen as t2
)
13 Шурик71
 
11.12.23
20:03
(0)

SELECT
СпрН.ID AS [Аналог $Справочник.Номенклатура]
FROM
$Справочник.Номенклатура AS СпрН With (NOLOCK)
INNER JOIN
$Справочник.СвойстваНоменклатуры AS СпрСвойстваНоменкл1 With (NOLOCK) ON СпрСвойстваНоменкл1.ParentExt = СпрН.ID
and $СпрСвойстваНоменкл1.ВидСвойства = &ВидСвойства1
and $СпрСвойстваНоменкл1.ЗначениеСвойства = &ЗначениеСвойства1
INNER JOIN
$Справочник.СвойстваНоменклатуры AS СпрСвойстваНоменкл2 With (NOLOCK) ON СпрСвойстваНоменкл2.ParentExt = СпрН.ID
and $СпрСвойстваНоменкл2.ВидСвойства = &ВидСвойства2
and $СпрСвойстваНоменкл2.ЗначениеСвойства = &ЗначениеСвойства2
INNER JOIN
$Справочник.СвойстваНоменклатуры AS СпрСвойстваНоменкл3 With (NOLOCK) ON СпрСвойстваНоменкл3.ParentExt = СпрН.ID
and $СпрСвойстваНоменкл3.ВидСвойства = &ВидСвойства3
and $СпрСвойстваНоменкл3.ЗначениеСвойства = &ЗначениеСвойства3
14 Sserj
 
11.12.23
20:05
Если тебе нужно чтобы было полное совпадение, т.е. нужна номенклатура у которой одновременно 3 свойства с нужными значениями то как вариант можно добавить группировку и having:

select
  СпрСвойстваНоменкл.ParentExt AS [Аналог $Справочник.Номенклатура]
  sum(СпрСвойстваНоменкл.ParentExt) as [Совпадения]
from
  $Справочник.СвойстваНоменклатуры AS СпрСвойстваНоменкл With (NOLOCK)
  join всеУсловия on (
  $СпрСвойстваНоменкл.ВидСвойства = всеУсловия.Свойство
  and $СпрСвойстваНоменкл.ЗначениеСвойства = всеУсловия.Значение)
goup by
  СпрСвойстваНоменкл.ParentExt
having
  sum(СпрСвойстваНоменкл.ParentExt) > 2
15 Sserj
 
11.12.23
20:07
Тьфу, не
sum(СпрСвойстваНоменкл.ParentExt) as [Совпадения]
a
count(СпрСвойстваНоменкл.ParentExt) as [Сопадения]
16 AAA
 
11.12.23
20:12
Да, я ступил, никаких OR не надо. Если требуется наличие всех свойств (в примере трех), то конечно надо делать как в (14)
Такой запрос легко сгенерировать
17 zenon46
 
12.12.23
08:55
(14) да, именно так, нужно найти номенклатуру у которой будет одновременно 3 свойства с 3 нужными значениями. 3 - это как для примера, а так может быть разное количество.
18 Aleksey
 
12.12.23
09:24
Вид свойств является владелец для значения свойств. И вряд ли у тебя будет вариант что владелец значения не совпадет с видом (если конечно кто то программно не на косячил)

Я к тому что отбор по виду свойств можно пренебречь
19 Андрей_Андреич
 
naïve
12.12.23
09:38
select
  СпрСвойстваНоменкл.ParentExt AS [Аналог $Справочник.Номенклатура]
from
  $Справочник.СвойстваНоменклатуры AS СпрСвойстваНоменкл With (NOLOCK)
  join всеУсловия on (
  $СпрСвойстваНоменкл.ВидСвойства = всеУсловия.Свойство
  and $СпрСвойстваНоменкл.ЗначениеСвойства = всеУсловия.Значение)
goup by
  СпрСвойстваНоменкл.ParentExt
having
  Count(*) > 2
20 uno-group
 
12.12.23
11:41
(9) 3-для примера это значение или количество свойств?
или может быть поиск по условию где 1 или 5 свойств.
тип продукции-Вино
цвет-Красное
вкус-сухое
страна-Испания
год -2005
тогда проще отсекать список после выбора каждого свойства и дальше работать уже с ним, чем делать динамический запрос.
21 zenon46
 
12.12.23
12:04
(18) так и есть, спасибо за наводку
22 АгентБезопасной Нацио
 
12.12.23
12:44
(18) беда только в том, что он укладывает короткие id'ы значений, а  их уникальность не гарантирована (даже наеборот, гарантирована неуникальность). Но теоретически - да, можно по длиннным идам значений, без учета свойств.
(20) ничего не нужно отсекать. И динамический запрос тоже не нужен
23 АгентБезопасной Нацио
 
12.12.23
13:03
+(22) кстати, тогда при формировании как в (18) полной таблицы более чем возможны косяки.
AdBlock убивает бесплатный контент. 1Сергей