Значение SQL-запроса в зависимости от нескольких значений других связанных таблиц - PullRequest
0 голосов
/ 11 апреля 2019

Прежде всего, извините, если название не совсем описательное, но я не знал, как описать, чего я хочу достичь. Моя система баз данных - SQL Server 2008 R2. Проблема заключается в следующем:

У меня есть две таблицы, A и B, с отношением 1 .. *, связанным идентификатором таблицы A. Я хочу запросить таблицу A с одним значением таблицы B в зависимости от этого правила:

  1. Если в таблице B нет подходящих записей, напишите «red»
  2. Если все записи в таблице B "НЕТ", напишите "красный"
  3. Если все записи в таблице B "ВСЕ", тогда напишите "зеленый"
  4. Если у нас есть смесь «НЕТ» и «ВСЕ», то напишите «желтый»
  5. Если какая-либо из совпадающих строк в таблице B является "ЧАСТИЧНОЙ", тогда напишите "желтый"

«ВСЕ», «ЧАСТИЧНЫЙ», «НЕТ» - это единственные доступные значения в таблице B, в случае любого.

Может ли кто-нибудь помочь мне получить это? Спасибо за вашу помощь

Ответы [ 2 ]

3 голосов
/ 11 апреля 2019

Предполагая, что таблица A имеет столбец с именем id, а таблица B имеет столбец с именами a_id и value, вы можете использовать комбинацию outer join и некоторого group ing для подачи case выписать некоторые совокупные значения.

select
    a.id,
    case
        when (max(b.a_id) is null) then "red" -- No match found
        when (min(b.value) = "NONE" and max(b.value) = "NONE") then "red" -- All B values are "NONE"
        when (min(b.value) = "ALL" and max(b.value) = "ALL") then "green" -- All B values are "ALL"
        when (max(case when (b.value = "PARTIAL") then 1 else 0 end) = 1) then "yellow" -- At least one B value contains "PARTIAL"
        when (max(case when (b.value = "NONE") then 1 else 0 end) = 1 and max(case when (b.value = "ALL") then 1 else 0 end) = 1) then "yellow" -- A mix of "NONE" and "ALL"
        else "Undefined"
    end
from
    table_a a
    left outer join table_b b
        on (a.id=b.a_id)
group by
    a.id

Большая часть логики здесь в выражении case. Использование min() и max() для сравнения значений в таблице B довольно просто и должно быть самоочевидным - если нет, просто добавьте min(b.value) и max(b.value) в ваш оператор выбора, чтобы увидеть, какие значения выводятся , чтобы помочь визуализировать это. Самое сложное для понимания - это правило для «частичного». Эта часть оператора case оценивает значение каждой строки из таблицы B, и если она является «частичной», то она возвращает значение «1» для этой строки. После того, как запрос оценил все строки B для группы, он выбирает значение max(), чтобы посмотреть, было ли когда-либо возвращено «1».

2 голосов
/ 11 апреля 2019

Вы можете агрегировать, а затем использовать предложение CASE для сортировки дел, например:

select
  a.*,
  case when x.id is null then 'red' -- rule #1
       when x.partial > 0 then 'yellow' -- rule #5
       when x.none > 0 and x.all = 0 then 'red' -- rule #2
       when x.none = 0 and x.all > 0 then 'green' -- rule #3
       when x.none > 0 and x.all > 0 then 'yellow' -- rule #4
       else 'undefined case' -- safety net, for future changes
  end as color
from a
left join (
  select
    a.id,
    sum(case when b.state = 'NONE' then 1 end) as none,
    sum(case when b.state = 'ALL' then 1 end) as all,
    sum(case when b.state = 'PARTIAL' then 1 end) as partial
  from a
  join b on b.a_id = a.id
  group by a.id
) x on a.id = x.id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...