Замена значения столбца несколькими значениями из другой таблицы - DB2

У меня есть сложный запрос ((Q1 union Q2) пересекается (Q3 union Q4)). Теперь проблема заключается в том, что один из столбцов, участвующих в запросах, имеет значение «Компания». Это значение может быть названием конкретной компании или значением «ВСЕ», что означает все компании. У меня есть отдельная таблица компаний, в которой перечислены названия компаний. Теперь логика заключается в том, что если один из запросов в пересечении имеет значение «ВСЕ», а другой запрос — это компания «C1», результат должен возвращать «C1». Но в настоящее время, поскольку «ALL» не соответствует «C1» в качестве строкового значения, пересечение ничего не возвращает. Могу ли я в любом случае заменить значение строки «ВСЕ» всеми названиями компаний, а затем выполнить пересечение? Я хочу выполнять все операции через SQL, потому что обрабатывать его в коде будет очень громоздко. Я использую DashDB, основанный на DB2.


person Indrani    schedule 31.08.2017    source источник
comment
Вместо intersect используйте INNER JOIN — вам нужно соединить все столбцы, а столбец company будет выглядеть как AND (T1.[Company] = T2.[Company] OR T1.[Company] = 'ALL')   -  person gotqn    schedule 31.08.2017
comment
Спасибо за ответ. Я постараюсь и дам вам знать. Но у меня путаница. Обе таблицы будут иметь столбец Company. Итак, какую сторону указать в предложении select? T1.Компания или T2. Компания? Мне нужно значение компании, которое не «ВСЕ»? Как узнать, в какой таблице он будет?   -  person Indrani    schedule 31.08.2017
comment
Спасибо за внутреннее присоединение и присоединение по критериям «ВСЕ». Подход сработал.   -  person Indrani    schedule 01.09.2017
comment
Вы можете опубликовать свой код и принять свой собственный ответ.   -  person gotqn    schedule 01.09.2017


Ответы (3)


Это должно работать:

select
    company_name
    ,the
    ,other
    ,columns
from 
(
    select distinct
        company_name = ca.company_name
        ,the
        ,other
        ,columns
    from Q1
        inner join companies_table ca
            on Q1.company_name = ca.company_name
            or Q1.company_name = 'ALL'

    union

    select distinct
        company_name = ca.company_name
        ,the
        ,other
        ,columns
    from Q2
        inner join companies_table ca
            on Q2.company_name = ca.company_name
            or Q2.company_name = 'ALL'
) a

intersect

select
    company_name
    ,the
    ,other
    ,columns
from 
(
    select distinct
        company_name = ca.company_name
        ,the
        ,other
        ,columns
    from Q3
        inner join companies_table ca
            on Q3.company_name = ca.company_name
            or Q3.company_name = 'ALL'

    union

    select distinct
        company_name = ca.company_name
        ,the
        ,other
        ,columns
    from Q4
        inner join companies_table ca
            on Q4.company_name = ca.company_name
            or Q4.company_name = 'ALL'
) b
person Raphael Müllner    schedule 31.08.2017
comment
Спасибо за ваш ответ. Я думаю, что перекрестное применение работает только в SQL Server. Я использую DB2 здесь. Есть ли альтернатива перекрестному применению в DB2? - person Indrani; 31.08.2017
comment
Извините, не знал, что DB2 не поддерживает перекрестное применение. Я обновил свой ответ решением, которое также должно работать, как было предложено gotqn. - person Raphael Müllner; 31.08.2017
comment
Этот подход сработал!! Пришлось немного изменить запрос. Включен также случай, когда пункт. Спасибо за помощь. - person Indrani; 01.09.2017
comment
Пожалуйста! Пожалуйста, отметьте это как ответ, если это решило вашу проблему. - person Raphael Müllner; 01.09.2017

Вы можете упростить свой запрос следующим образом:

SELECT AA.OBJECT_TYPE, AA.OBJECT_FILTER_ID, 
CASE WHEN BB.OBJECT_FILTER_VALUE = 'ALL' THEN AA.OBJECT_FILTER_VALUE ELSE BB.OBJECT_FILTER_VALUE END AS OBJECT_FILTER_VALUE 
FROM COMPANY AS AA 
INNER JOIN DETAILS AS BB ON (AA.OBJECT_TYPE, AA.OBJECT_FILTER_ID)=(BB.OBJECT_TYPE, BB.OBJECT_FILTER_ID) 
AND(AA.OBJECT_FILTER_VALUE = BB.OBJECT_FILTER_VALUE OR AA.OBJECT_FILTER_VALUE = 'ALL' OR BB.OBJECT_FILTER_VALUE = 'ALL')
person Esperento57    schedule 05.09.2017
comment
Это выглядит круто. Не знал об этом синтаксисе. Спасибо за ваше предложение. - person Indrani; 06.09.2017

Это запрос, который решил мою проблему (я удалил сложности из запроса и включил только те части, которые связаны с этим вопросом)

SELECT 
AA.OBJECT_TYPE, 
AA.OBJECT_FILTER_ID, 
CASE WHEN BB.OBJECT_FILTER_VALUE = 'ALL' 
  THEN AA.OBJECT_FILTER_VALUE 
  ELSE BB.OBJECT_FILTER_VALUE 
  END AS OBJECT_FILTER_VALUE FROM 
( 
    SELECT 
    OBJECT_TYPE, 
    OBJECT_FILTER_ID, 
    OBJECT_FILTER_VALUE 
    from COMPANY
) AS AA 
INNER JOIN 
( 
    SELECT 
    OBJECT_TYPE ,
    OBJECT_FILTER_ID ,
    OBJECT_FILTER_VALUE 
    FROM DETAILS
) AS BB 
ON 
AA.OBJECT_TYPE = BB.OBJECT_TYPE AND 
AA.OBJECT_FILTER_ID = BB.OBJECT_FILTER_ID AND
(
AA.OBJECT_FILTER_VALUE = BB.OBJECT_FILTER_VALUE OR 
AA.OBJECT_FILTER_VALUE = 'ALL' OR 
BB.OBJECT_FILTER_VALUE = 'ALL'
)
person Indrani    schedule 04.09.2017