11.02.2012 19:42
AlexeyF
 
Подскажите куда копать?
Есть таблица с шапками документов - SUPERMAG.SERJ (ID документа и пара доп признаков)
Надо к каждому документу подтянуть спецификацию документа SMSpec, налоги SMSpecTax, карточка товара SMCard, себестоимость FFMapRep и при этом отфильтровать артикулы по условию принадлежности к каким то группам.
Когда у интересующих групп вложимость в дереве классификатора была одинаковая, использовалась конструкция следующего вида, и всё работало на ура: (запрос показывает все артикулы для документа БР420120101@45, за исключением групп '6789', '7891', '9400', '9402')
select * from
SUPERMAG.SERJ serj
left join SUPERMAG.FFMapRep f on f.SALEID=serj.ID
left join SUPERMAG.smspectax tax on f.SALEID=tax.DOCID and f.SALETYPE=tax.DOCTYPE and f.SALESPECITEM=tax.SPECITEM
where
(select ts.id from SUPERMAG.SMCARD c
left join SUPERMAG.sacardclass t on t.ID=c.IDCLASS
left join SUPERMAG.SACARDCLASS ts on ts.TREE=SUBSTR(t.TREE,0, 10)
where ARTICLE=f.article
) not in ('6789', '7891', '9400', '9402')
and
serj.id = 'БР420120101@45'


Но потом понадобилось производить эти выборки для нескольких групп товаров с разной вложимостью дерева классификатора.
select * from SUPERMAG.SERJ serj
left join SUPERMAG.FFMapRep f on f.SALEID=serj.ID
left join SUPERMAG.smspectax tax on f.SALEID=tax.DOCID and f.SALETYPE=tax.DOCTYPE and f.SALESPECITEM=tax.SPECITEM
where
(select ts.id from SUPERMAG.SMCARD c
left join SUPERMAG.sacardclass t on t.ID=c.IDCLASS
left join SUPERMAG.SACARDCLASS ts on ts.TREE=SUBSTR(t.TREE,0, 9)
where ARTICLE=f.article
)!='9092'
and
(select ts.id from SUPERMAG.SMCARD c
left join SUPERMAG.sacardclass t on t.ID=c.IDCLASS
left join SUPERMAG.SACARDCLASS ts on ts.TREE=SUBSTR(t.TREE,0, 10)
where ARTICLE=f.article
) not in ('6789', '7891', '9400', '9402')
and
(select ts.id from SUPERMAG.SMCARD c
left join SUPERMAG.sacardclass t on t.ID=c.IDCLASS
left join SUPERMAG.SACARDCLASS ts on ts.TREE=SUBSTR(t.TREE,0, 11)
where ARTICLE=f.article
) not in ('10093', '10095')
and
serj.id = 'БР420120101@45'


Это я думал, что если добавить ещё одно условие (select ...) not in ('xxx'), то всё будет как обычно. Но оказалось если в WHERE присутствуют два и более условия такого типа, соединённых AND'ом весь select возвращает погоду.
Т.е. в первом случае у меня все артикулы документа БР420120101@45, не принадлежащие группам '6789', '7891', '9400', '9402'. А во втором случае хотелось что бы все артикулы кроме уже 7-ти групп, но на выходе две записи и ни каких ошибок. При этом точно известно, что этих артикулов должно быть очень много.
Причём если наоборот нужно получить из документа артикулы, которые принадлежат группам, заменяем условия и AND на OR, объединяем скобочками и работает правильно.
where
((select ts.id from SUPERMAG.SMCARD c
left join SUPERMAG.sacardclass t on t.ID=c.IDCLASS
left join SUPERMAG.SACARDCLASS ts on ts.TREE=SUBSTR(t.TREE,0, 9)
where ARTICLE=f.article
)='9092'
or
(select ts.id from SUPERMAG.SMCARD c
left join SUPERMAG.sacardclass t on t.ID=c.IDCLASS
left join SUPERMAG.SACARDCLASS ts on ts.TREE=SUBSTR(t.TREE,0, 10)
where ARTICLE=f.article
) in ('6789', '7891', '9400', '9402')
or
(select ts.id from SUPERMAG.SMCARD c
left join SUPERMAG.sacardclass t on t.ID=c.IDCLASS
left join SUPERMAG.SACARDCLASS ts on ts.TREE=SUBSTR(t.TREE,0, 11)
where ARTICLE=f.article
) in ('10093', '10095')
)

and
serj.id = 'БР420120101@45'


Подскажите как можно выкрутиться в этой ситуации ? Как ещё можно фильтровать по нескольким группам ?

Oracle Enterprise 10.2.0.4.0
11.02.2012 20:31
OlegON
 
сочувствую, поскольку объяснить то, что ты хочешь, трудно... рекомендации:
1) вырвать из задницы с мясом руки тому Сержу, который создает таблички в схеме SUPERMAG
2) отформатировать код, иначе с экрана его крайне трудно читать, а есть подозрение, что ты запутался в скобках или в том, что с чем сравниваешь
3) попробовать не использовать ANSI нотацию в пользу плюсовой, несмотря на то, что оракл продвигает ANSI, несколько раз спотыкался, что работает она как-то странно
11.02.2012 21:23
AlexeyF
 
Скобки проверялись, пере проверялись уже много раз. А вот различия синтаксиса я не в курсе был - вот с этим завтра буду плотно разбираться.
Погуглил - проблем скорее всего в ANSI
12.02.2012 18:19
AlexeyF
 
Так и оказалось.
заменил родительскую конструкцию вида:
select * from
SUPERMAG.SERJ serj
left join SUPERMAG.FFMapRep f on f.SALEID=serj.ID
left join SUPERMAG.smspectax tax on f.SALEID=tax.DOCID and f.SALETYPE=tax.DOCTYPE and f.SALESPECITEM=tax.SPECITEM
where
.........

на
select * from
SUPERMAG.SERJ serj,
SUPERMAG.FFMapRep f,
SUPERMAG.smspectax tax
where
f.saleid=serj.id and f.saleid=tax.docid and f.saletype=tax.doctype and f.salespecitem=tax.specitem
.........

Вот я бы с этим сам долго бы разбирался...
А что ошибками поддержки ANSI в 11-й версии, то же бывают глюки ???
12.02.2012 20:39
OlegON
 
Про 11ю не скажу, пока еще не рассматриваю ее в качестве основной, хотя больше по причине "руки не дошли". Но где-то спотыкался и на 9 и на 10ке. В 11й где-то была дока с уговорами перейти на ANSI, но мне плюсики роднее, да и вроде они пока не deprecated.
13.02.2012 07:16
Mtirt
 
А нельзя засунуть нужные карточки в ассортимент и выбирать по нему?
Чтобы упростить условие...
А в ассортимент можно последовательно, скриптом засунуть всё, что нужно или не нужно...
13.02.2012 08:51
AlexeyF
 
Про ассортимент идея мне в голову пришла, когда столкнулся с этим скрптом.
Если у меня получится, то буду дальше думать про упрощение-убыстрения оного, в том числе с пом ассортимента.
Сейчас нужно что бы он в принципе вернул то что надо.
(раньше было деление на одну группу и всё остальное, теперь неск групп и всё остальное).
Задача чуть чуть изменилась, а разработчик у нас не работает уже несколько месяцев.
13.02.2012 08:54
Mtirt
 
Ну тогда присоединяюсь к Олегу.
Приведи тот запрос, который неправильно работаеет в теге CODE, что-ли.
Сложно мне искать ошибку в твоем мелком шрифте...
13.02.2012 10:45
Mtirt
 
Такое условие тебя устроит?


Код:
 
(select id from SUPERMAG.sacardclass
minus
((select ts.id from SUPERMAG.SMCARD c
left join SUPERMAG.sacardclass t on t.ID=c.IDCLASS
left join SUPERMAG.SACARDCLASS ts on ts.TREE=SUBSTR(t.TREE,0, 9)
where ARTICLE=f.article
)='9092'
and
(select ts.id from SUPERMAG.SMCARD c
left join SUPERMAG.sacardclass t on t.ID=c.IDCLASS
left join SUPERMAG.SACARDCLASS ts on ts.TREE=SUBSTR(t.TREE,0, 10)
where ARTICLE=f.article
) in ('6789', '7891', '9400', '9402')
and
(select ts.id from SUPERMAG.SMCARD c
left join SUPERMAG.sacardclass t on t.ID=c.IDCLASS
left join SUPERMAG.SACARDCLASS ts on ts.TREE=SUBSTR(t.TREE,0, 11)
where ARTICLE=f.article
) in ('10093', '10095')
))
И я не совсем понимаю, зачем тебе два объединения с SACARDCLASS...
13.02.2012 10:59
vdm
 
Цитата:
Mtirt И я не совсем понимаю, зачем тебе два объединения с SACARDCLASS...
Присоединяюсь.
Выглядит очень странно, примерно как "отобрать группы с длиной(!) до 9-10-11 символов"
У вас tree так хитро устроено, что его длина что-то означает?
Часовой пояс GMT +3, время: 06:55.

Форум на базе vBulletin®
Copyright © Jelsoft Enterprises Ltd.
В случае заимствования информации гипертекстовая индексируемая ссылка на Форум обязательна.