Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Помогите правильно объединить 2 таблицы  [new]
InVoKeR
Member

Откуда:
Сообщений: 12
Добрый день. Помогите пожалуйста с запросом. Не могу понять в чем ошибся.
Есть 2 таблицы tab1, tab2.
В tab1 есть следующие поля id_dpt, id, name, type, code
В tab2 следующие поля name, type, code
Подразумевается что в таблице tab2 данные корректны (загружаются из справочника),
а в tab1 данные вводятся пользователем (т.е. могут содержать ошибки)
Задача заключается в том, чтобы по критерю tab1.name = tab2.name, tab1.type =tab2.type, tab1.code<> tab1.code
проблемма в том, что в таблице tab1 может содержаться запись, которой в таблице tab2 соответствует N аналогов (т.е. name и type совпадают, а коды разные)
Нужно чтобы в результирующей выборке:
1. для случия множественного совпадения выводился только один вариант где tab1.code<> tab1.code
2. если в таблице tab2 есть запись с условиями tab1.name = tab2.name, tab1.type =tab2.type, tab1.code = tab1.code, и так же есть записи удовлетворяющие условию tab1.name = tab2.name, tab1.type =tab2.type, tab1.code <> tab1.code, то такую запись не выводить (т.е. елси есть хотябы одно совпадение по условию tab1.name = tab2.name, tab1.type =tab2.type, tab1.code = tab1.code, то не выводить запись в результирующую выборку)
вот что соорудил я:
            SELECT DISTINCT ac.id_dpt, ac.ID, ac.code1, g.NAME,
                            g.ocatd, g.type
                       FROM tab1 ac, tab2 g
                      WHERE TRIM (UPPER (ac.NAME)) = TRIM (UPPER (g.NAME))
                        AND ac.id_dpt = 77
                        AND ac.id_dptm_rgn = 77
                        AND ac.idm_rgn = 1171
                        AND ac.dt_fr <= SYSDATE
                        AND ac.dt_to > SYSDATE
                        AND g.type NOT IN ('р-н', 'обл', 'тер')
                        AND ac.id_dptm_ar IS NULL
                        AND ac.idm_ar IS NULL
                        AND g.code <> ac.code1
                        AND g.type =
                               (SELECT REPLACE (CV.short_name, '.')
                                  FROM type_val CV
                                 WHERE CV.id_type_list = 'TP_PP'
                                   AND CV.dt_fr <= SYSDATE
                                   AND CV.dt_to > SYSDATE
                                   AND CV.is_enabled = 1
                                   AND CV.ID = ac.id_tppp)
                        AND ac.id_tppp = 'TPPP_CIT'
            UNION
            SELECT DISTINCT ac.id_dpt, ac.ID, ac.extrn_code1, g.NAME, g.ocatd,
                            g.socr
                       FROM tab1 ac, tab2 g
                      WHERE TRIM (UPPER (ac.NAME(+))) = TRIM (UPPER (g.NAME))
                        AND ac.id_dpt = 77
                        AND TRIM (SUBSTR (g.code, 1, 5)) =
                               (SELECT TRIM (SUBSTR (aa.code1, 1, 5))
                                  FROM tab3 aa
                                 WHERE aa.id_dpt = ac.id_dptm_ar
                                   AND aa.ID = ac.idm_ar
                                   AND aa.dt_fr <= SYSDATE
                                   AND aa.dt_to > SYSDATE)
                        AND ac.id_dptm_rgn = 77
                        AND ac.idm_rgn = 1171
                        AND ac.dt_fr <= SYSDATE
                        AND ac.dt_to > SYSDATE
                        AND g.socr NOT IN ('р-н', 'обл', 'тер')
                        AND g.code <> ac.code1
                        AND g.type =
                               (SELECT REPLACE (CV.short_name, '.')
                                  FROM type_val CV
                                 WHERE CV.id_type_list = 'TP_PP'
                                   AND CV.dt_fr <= SYSDATE
                                   AND CV.dt_to > SYSDATE
                                   AND CV.is_enabled = 1
                                   AND CV.ID = ac.id_tppp)
                        AND NOT EXISTS (
                               SELECT 1
                                 FROM tab2 tt
                                WHERE TRIM (UPPER (tt.NAME)) =
                                                        TRIM (UPPER (ac.NAME))
                                  AND TRIM (tt.code) = TRIM (ac.code1))
                        AND g.code NOT LIKE ('___________99');

сейчас у меня на одно значение в tab1 выводит например 3 значения, если в tab2 есть 3 записи удовлетворяющих условию tab1.name = tab2.name, tab1.type =tab2.type, tab1.code<> tab1.code.
а нужно чтоб выводилась только оодна запись, т.к. в начальной таблице она одна
22 дек 08, 16:01    [6604142]     Ответить | Цитировать Сообщить модератору
 Re: Помогите правильно объединить 2 таблицы  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
связываете 2 таблицы (по первым двум условиям), группируете, в having пишите что-то типа count(*) = 1 or not(min(decode( tab2.code, tab1.code, 1)) = 1 and min(decode( tab2.code, tab1.code, null, 1))=1))
ну и в селекте - тоже min/max с decode/case
PS: писано не очень аккуратно, но надеюсь общий смысл понятен
22 дек 08, 18:33    [6605247]     Ответить | Цитировать Сообщить модератору
 Re: Помогите правильно объединить 2 таблицы  [new]
InVoKeR
Member

Откуда:
Сообщений: 12
может я немного не понял... условие having count(*)=1 призвано оставить одну строку (если их несколько), а условие not(min(decode( ac.code1, g.code, 1)) = 1
and min(decode(ac.code1, g.code, null, 1))=1)
насчет добавить с селект, я что то не так делаю, но не получилось :(
а такой звпрос возвращает 2 записи вместо одной
            SELECT  ac.id_dpt, ac.ID, ac.code1, g.NAME,
                            g.code, g.type
                       FROM tab1 ac, tab2 g
                      WHERE TRIM (UPPER (ac.NAME)) = TRIM (UPPER (g.NAME))
                        AND ac.id_dpt = 77
                        AND ac.id_dptm_rgn = 77
                        AND ac.idm_rgn = 1171
                        AND ac.dt_fr <= SYSDATE
                        AND ac.dt_to > SYSDATE
                        AND g.type NOT IN ('р-н', 'обл', 'тер')
                        AND ac.id_dptm_ar IS NULL
                        AND ac.idm_ar IS NULL
                        and ac.code1 is not null
                        AND g.code <> ac.code1
                      /* and (min(decode( ac.code1, g.code, 1)) = 1 
                        and min(decode(ac.code1, g.code, null, 1))=1)*/
                        AND g.type =
                               (SELECT REPLACE (CV.short_name, '.')
                                  FROM cdfr_val CV
                                 WHERE CV.id_cdfr_list = 'TP_PP'
                                   AND CV.dt_fr <= SYSDATE
                                   AND CV.dt_to > SYSDATE
                                   AND CV.is_enabled = 1
                                   AND CV.ID = ac.id_tppp)
                        AND ac.id_tppp = 'TPPP_CIT'
            UNION
            SELECT  ac.id_dpt, ac.ID, ac.code1, g.NAME, g.code,
                            g.type
                       FROM tab1 ac, tab2 g
                      WHERE TRIM (UPPER (ac.NAME(+))) = TRIM (UPPER (g.NAME))
                        AND ac.id_dpt = 77
                        AND TRIM (SUBSTR (g.code, 1, 5)) =
                               (SELECT TRIM (SUBSTR (aa.code1, 1, 5))
                                  FROM adrs_area aa
                                 WHERE aa.id_dpt = ac.id_dptm_ar
                                   AND aa.ID = ac.idm_ar
                                   AND aa.dt_fr <= SYSDATE
                                   AND aa.dt_to > SYSDATE)
                        AND ac.id_dptm_rgn = 77
                        AND ac.idm_rgn = 1171
                        AND ac.dt_fr <= SYSDATE
                        AND ac.dt_to > SYSDATE
                        AND g.type NOT IN ('р-н', 'обл', 'тер')
                        AND g.code <> ac.code1
                    /*  and (min(decode( ac.code1, g.code, 1)) = 1 
                        and min(decode(ac.code1, g.code, null, 1))=1)*/
                        and ac.code1 is not null
                        AND g.type =
                               (SELECT REPLACE (CV.short_name, '.')
                                  FROM cdfr_val CV
                                 WHERE CV.id_cdfr_list = 'TP_PP'
                                   AND CV.dt_fr <= SYSDATE
                                   AND CV.dt_to > SYSDATE
                                   AND CV.is_enabled = 1
                                   AND CV.ID = ac.id_tppp)
                      /*  AND NOT EXISTS (
                               SELECT 1
                                 FROM tab2 tt
                                WHERE TRIM (UPPER (tt.NAME)) =
                                                        TRIM (UPPER (ac.NAME))
                                  AND TRIM (tt.code) = TRIM (ac.code1))*/
                        AND g.code NOT LIKE ('___________99')
                        group by ac.id_dpt, ac.ID, ac.code1, g.NAME, g.code,
                            g.type
                       having count(*)=1 or
                       not(min(decode( ac.code1, g.code, 1)) = 1 
                        and min(decode(ac.code1, g.code, null, 1))=1)
                         
                        
                        

ID_DPT          ID CODE1          NAME                       CODE       TYPE
------ ----------- -------------------- -------------------- ----------- ----------
    77       30347 60224875003    NAME1                   60224850005      х
    77       30347 60224875003    NAME1                   60224875001      х
23 дек 08, 12:57    [6607629]     Ответить | Цитировать Сообщить модератору
 Re: Помогите правильно объединить 2 таблицы  [new]
InVoKeR
Member

Откуда:
Сообщений: 12
случай 2. если в таблице tab2 есть запись с условиями tab1.name = tab2.name, tab1.type =tab2.type, tab1.code = tab1.code, и так же есть записи удовлетворяющие условию tab1.name = tab2.name, tab1.type =tab2.type, tab1.code <> tab1.code, то такую запись не выводить (т.е. елси есть хотябы одно совпадение по условию tab1.name = tab2.name, tab1.type =tab2.type, tab1.code = tab1.code, то не выводить запись в результирующую выборку)
я победил, а вот с вариантом когда как в примере выше одному code1 соответствуют 2 (или несколько) code победить не получается.
23 дек 08, 17:20    [6609781]     Ответить | Цитировать Сообщить модератору
 Re: Помогите правильно объединить 2 таблицы  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
InVoKeR
насчет добавить с селект, я что то не так делаю, но не получилось :(
а такой звпрос возвращает 2 записи вместо одной
А зачем Вы оставили union? А две записи у Вас потому, что в условие группировки Вы написали code, которого там быть не должно.
Насчет count(*) = 1 - это я погорячилась.
24 дек 08, 12:21    [6612643]     Ответить | Цитировать Сообщить модератору
 Re: Помогите правильно объединить 2 таблицы  [new]
InVoKeR
Member

Откуда:
Сообщений: 12
CODE должен быть в результирующей выборке и значит в группировке тоже должен присутствовать ...
24 дек 08, 13:19    [6613201]     Ответить | Цитировать Сообщить модератору
 Re: Помогите правильно объединить 2 таблицы  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
InVoKeR
CODE должен быть в результирующей выборке и значит в группировке тоже должен присутствовать ...
Чтобы быть в результирующей выборке - не обязательно присутствовать во фразе group by...
24 дек 08, 14:40    [6614052]     Ответить | Цитировать Сообщить модератору
 Re: Помогите правильно объединить 2 таблицы  [new]
InVoKeR
Member

Откуда:
Сообщений: 12
Cпасибо за подсказку, очень благодарен :) . Запрос победил
25 дек 08, 12:41    [6619019]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить