Oracle. Если запись существует по первому утверждению, игнорируйте второе - PullRequest
0 голосов
/ 30 января 2020

У меня вопрос, как решить мою проблему.

У меня есть процедура, где внутри меня это SELECT внутри LEFT OUTER JOIN Ведьма возвращает мне некоторые значения:

SELECT * FROM database1 data1
                        JOIN database2 data2 ON data2.id = data1.attr_id
                        JOIN database3 data3 ON data3.attr_id = data2.id
                        JOIN database4 data4 ON data4.objt_attr_id = data3.id
                        JOIN database5 data5 ON data5.stya_id = data4.id
                            AND data5.value = 1
        JOIN database6 data6 ON data6.id = data5.sero_id
        JOIN database7 data7 ON srv.id = data6.srv_id
        JOIN database8 data8 ON data8.code IN ('CALC1','CALC2')
        WHERE data1.ordet_id IN (data8.id)

Как видите, он ищет CALC1 и CALC2, а затем ищет по их ID's в data1.ordet_id. Естественно, он вернул мне 2 записи ведьмы не правильно.

Как сделать чек. Когда скрипт найдет запись с CALC1, он пропускает проверку на CALC2, поэтому скрипт возвращает только 1 запись к CALC1 (не так, как сейчас для обоих). И наоборот, если по CALC1 запись не найдена, он проверяет CALC2

Ответы [ 2 ]

1 голос
/ 30 января 2020

Соединитесь дважды с OUTER JOIN (т.е. вы не потеряете запись, если соответствующий код не существует, но вы не продублируете результат ) и получите приоритетный код с COALESCE из первое или второе присоединение.

SELECT 
   data1.ordet_id ,
   COALESCE(data81.code, data82.code) code
FROM data1.ordet_id 
LEFT OUTER JOIN data81 ON data1.ordet_id = data81.id and data81.code = 'CALC1'
LEFT OUTER JOIN data82 ON data1.ordet_id = data82.id and data82.code = 'CALC2'
1 голос
/ 30 января 2020

Я думаю, вы можете воспользоваться аналитической функцией row_number следующим образом:

select * from
(SELECT data1.*, data2.*, .. data8.*, 
        row_number() over (partition by data1.ordet_id order by data8.code ) as rn 
        FROM database1 data1
        JOIN database2 data2 ON data2.id = data1.attr_id
        JOIN database3 data3 ON data3.attr_id = data2.id
        JOIN database4 data4 ON data4.objt_attr_id = data3.id
        JOIN database5 data5 ON data5.stya_id = data4.id
                            AND data5.value = 1
        JOIN database6 data6 ON data6.id = data5.sero_id
        JOIN database7 data7 ON srv.id = data6.srv_id
        JOIN database8 data8 ON data8.code IN ('CALC1','CALC2')
        WHERE data1.ordet_id IN (data8.id))
where rn = 1

- Обновление

В соответствии с нижеследующим комментарием, вы можно также использовать NOT EXISTS и комбинацию CASE..WHEN следующим образом:

SELECT  *
FROM
    DATABASE1 DATA1
    JOIN DATABASE2 DATA2 ON DATA2.ID = DATA1.ATTR_ID
    JOIN DATABASE3 DATA3 ON DATA3.ATTR_ID = DATA2.ID
    JOIN DATABASE4 DATA4 ON DATA4.OBJT_ATTR_ID = DATA3.ID
    JOIN DATABASE5 DATA5 ON DATA5.STYA_ID = DATA4.ID
                            AND DATA5.VALUE = 1
    JOIN DATABASE6 DATA6 ON DATA6.ID = DATA5.SERO_ID
    JOIN DATABASE7 DATA7 ON SRV.ID = DATA6.SRV_ID
    JOIN DATABASE8 DATA8 ON DATA8.CODE IN (
        'CALC1',
        'CALC2'
    )
WHERE
    CASE
        WHEN DATA8.CODE = 'CALC1' THEN DATA1.ORDET_ID
        WHEN DATA8.CODE = 'CALC2' THEN CASE
            WHEN NOT EXISTS (
                SELECT 1 FROM
                    DATABASE8 D8
                WHERE DATA1.ORDET_ID = D8.ID
                  AND D8.CODE = 'CALC1'
            ) THEN DATA1.ORDET_ID
        END
    END = DATA8.ID

Cheers !!

...