Можно ли перечислить все возможные роли пользователя с помощью оператора CASE из одной таблицы?[Teradata] - PullRequest
3 голосов
/ 13 мая 2019

enter image description here

Я выясняю, можно ли перечислить все 4 роли, которые должен иметь пользователь, с утверждением «Да» или «Нет» для каждой из них.Например.

SELECT DISTINCT Grantee, GranteeKind, RoleName, WhenGranted,
    CASE
        WHEN RoleName='Manager' THEN 'Yes'
        WHEN RoleName='Assistant' THEN 'Yes'
        WHEN RoleName='Executive' THEN 'Yes'
        WHEN RoleName='Deputy' THEN 'Yes'
                    ELSE NULL
            END AS "Already granted?"
    FROM DBC.RolesM
    WHERE Grantee='UserName' 
    AND RoleName IN
    ('Manager',
    'Assistant',
    'Executive',
    'Deputy');

Мой запрос извлекает приведенный ниже результат, и он на 100 процентов корректен.

Grantee    GranteeKind  RoleName    WhenGranted Already Granted? 
UserName    User    Manager         2018-01-30        Yes
UserName    User    Assistant       2016-01-30        Yes

Тем не менее, мне интересно, возможно ли получить что-то подобное, поэтому мыиметь явный ответ для ролей, которые не назначены.

Grantee    GranteeKind  RoleName    WhenGranted Already Granted? 
UserName    User    Manager         2018-01-30        Yes
UserName    User    Assistant       2016-01-30        Yes
UserName    User    Executive       2016-01-30        No
UserName    User    Deputy          2016-01-30        No

Ответы [ 3 ]

0 голосов
/ 13 мая 2019

Используйте cross join для генерации строк и затем left join для ввода значений.

К сожалению, Teradata усложняет создание списка ролей, но это должно сработать:

select g.Grantee, g.GranteeKind, r.RoleName, 
       rm.WhenGranted,
       (case when rm.RoleName is not null then 'Yes' else 'No' end) as already_granted
from (select distinct grantee, GranteeKind
      from DBC.RolesM
     ) g cross join
     (select distinct RoleName
      from DBC.RolesM
      where RoleName in ('Manager', 'Assistant', 'Executive', 'Deputy')
     ) r left join
     DBC.RolesM rm
     on rm.grantee = g.grantee and rm.rolename = r.rolename
0 голосов
/ 13 мая 2019

У меня сейчас нет доступа к моему ТД, поэтому я делаю это по памяти:

select Grantee, GranteeKind, RoleName,
    max(managerRole), max(AssistantRole), max(ExecutiveRole), max(DeputyRole)
from (
  SELECT DISTINCT Grantee, GranteeKind, RoleName, WhenGranted,
    CASE
        WHEN RoleName='Manager' THEN 'Yes' ELSE 'No'
    END as ManagerRole,
    CASE
        WHEN RoleName='Assistant' THEN 'Yes' ELSE 'No'
    END as AssistantRole,
    CASE
        WHEN RoleName='Executive' THEN 'Yes' ELSE 'No'
    END as ExecutiveRole,
    CASE
        WHEN RoleName='Deputy' THEN 'Yes' ELSE 'No'
    END AS DeputyRole
  FROM DBC.RolesM
  WHERE Grantee='UserName' 
    AND RoleName IN
    ('Manager',
    'Assistant',
    'Executive',
    'Deputy')
  ) as DT
group by 1, 2, 3
order by 1, 2;

надеюсь, синтаксических ошибок не будет.

В основном внутренний запрос создает такой список:

Grantee etc, ManagerRole, AssistantRole, etc
abc,             Yes          No
abc,             No           Yes
def,             Yes          No
def,             No           No

Затем внешний запрос выбирает совокупность каждого столбца. Мы делаем максимум, поэтому «Да» будет бить «Нет». Вы получите «Нет» только в том случае, если у пользователя нет этой роли.

Примечание. Существует предположение, что Grantee, GrantKind и RoleName одинаковы. Если нет, вы получите несколько записей на одного Получателя. Мне пришлось опустить «когда предоставлено», потому что это, вероятно, будет в разное время.

0 голосов
/ 13 мая 2019

Попробуйте запрос, указанный ниже, надеюсь, это поможет.

SELECT  *
FROM    ( SELECT  Grantee, GranteeKind, RoleName, WhenGranted, ROW_NUMBER() OVER (PARTITION BY RoleName ORDER BY id) AS RowNumber
    CASE
        WHEN RoleName='Manager' THEN 'Yes'
        WHEN RoleName='Assistant' THEN 'Yes'
        WHEN RoleName='Executive' THEN 'Yes'
        WHEN RoleName='Deputy' THEN 'Yes'
                    ELSE NULL
            END AS "Already granted?"
    FROM DBC.RolesM
    WHERE Grantee='UserName' 
    AND RoleName IN
    ('Manager',
    'Assistant',
    'Executive',
    'Deputy')) AS a
WHERE   a.RowNumber = 1
...