SQL: установить условное значение на основе различных критериев в другой таблице. - PullRequest
0 голосов
/ 18 июня 2020

Немного ново для SQL - db - это Snowflake, который, как мне кажется, соответствует ANSI

Основная таблица, показанная ниже. Возможны комбинации одной и той же проблемы / UPC / Warehouse / Date, поскольку новая запись добавляется всякий раз, когда сообщается о новой проблеме. Существуют и другие столбцы, но они не должны влиять на этот вопрос

enter image description here

Столбец исключения - это то, что я пытаюсь выяснить - он должен быть 'Y' если желаемая комбинация Issue / UPC / Warehouse и Date находится в таблице исключений, показанной ниже.

enter image description here

Сложная часть - это столбец LEVEL, определение того, должна ли совпадать комбинация UPC / Issue / Warehouse, или просто UPC / Issue, или просто UP C. Кроме того, записи в основной таблице должны находиться в диапазоне дат, чтобы их можно было исключить.

Визуально ожидаемый результат:

enter image description here

Это решение работает только на одном уровне (Issue / UPC / Warehouse), но я не могу понять, как сделать два других без перекрытия и возможности исключения записей при аварии.

update t
set exclude = 'Y'
where exists (select 1
              from exclusions e
              where e.issue_code = t.issue_code and
              e.upc = t.upc and
              e.warehouse = t.warehouse and
              t.date between e.date_from and e.date_to);

Ответы [ 4 ]

2 голосов
/ 18 июня 2020

Ответ Дэвида охватывает правильный подход с использованием условного выражения CASE , но убедитесь, что ваш запрос также явно включает проверку уровня в каждое условие. Вот подробный пример:

update t
set exclude = case
    when exists(
        select 1
        from exclusions e
        where 
                e.warehouse = t.warehouse
            and e.upc = t.upc
            and e.issue_code = t.issue_code
            and t.date between e.date_from and e.date_to
            and e.level = 'UPC/ISSUE/WAREHOUSE'
    ) then 'Y'
    when exists(
        select 1
        from exclusions e
        where 
                e.issue_code = t.issue_code
            and e.upc = t.upc
            and t.date between e.date_from and e.date_to
            and e.level = 'UPC/ISSUE'
    ) then 'Y'
    when exists(
        select 1
        from exclusions e
        where 
                e.upc = t.upc
            and t.date between e.date_from and e.date_to
            and e.level = 'UPC'
    ) then 'Y'
    else ''
end;
2 голосов
/ 18 июня 2020

Я не понимаю, чего не хватает вашему решению, но вы можете обрабатывать несколько различных ситуаций / выходных данных для столбца с помощью оператора case. Будет применяться только первое совпадение, чтобы предотвратить перекрытие.

Примерно так:

update t
set exclude = CASE
    WHEN EXISTS 
        (select 1
         from exclusions e
         where e.issue_code = t.issue_code and
             e.upc = t.upc and
             e.warehouse = t.warehouse and
             t.date between e.date_from and e.date_to
        ) THEN 'Y'
    WHEN --Other situation where it meets your criteria
        THEN 'Y'
    ELSE 'N'
END
;

Вы также можете использовать это, чтобы инвертировать ваш logi c, чтобы указать 'N' ситуации и по умолчанию - Y, если это имеет смысл.

1 голос
/ 18 июня 2020

Если я проигнорирую столбец level, я могу просто использовать null, чтобы увидеть, есть ли совпадение. Если этого достаточно, то:

update t
    set exclude = 'Y'
    where exists (select 1
                  from exclusions e
                  where (e.issue_code = t.issue_code or e.issue_code is null) and
                        (e.upc = t.upc or e.upc is null) and
                        (e.warehouse = t.warehouse or e.warehouse is null) and
                        t.date between e.date_from and e.date_to
                 );

Вы можете также использовать столбец level (я думаю, что вышесказанное более понятно). Примерно так:

update t
    set exclude = 'Y'
    where exists (select 1
                  from exclusions e
                  where (e.issue_code = t.issue_code or e.level not like '%ISSUE%') and
                        (e.upc = t.upc or e.level not like '%UPC%') and
                        (e.warehouse = t.warehouse or e.level like '%WAREHOUSE%') and
                        t.date between e.date_from and e.date_to
                 );
0 голосов
/ 18 июня 2020

Я согласен с тем, что сказал Дэвид, что вам нужно, это обновление с оператором case. Будьте осторожны с оператором case - будут выполнены только первые удовлетворенные критерии. так что сначала кодируйте наиболее распространенный случай, затем следующий наиболее распространенный ... наконец, наименее распространенный критерий.

...