2
votes

Est-il possible de lister tous les rôles d'utilisateurs possibles avec l'instruction CASE à partir d'une table? [TERADATA]

entrez la description de l'image ici

Je suis en train de déterminer s'il est possible de lister les 4 rôles qui l'utilisateur doit avoir une déclaration «Oui» ou «Non» à chacun. Par exemple.

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

Ma requête récupère le résultat ci-dessous et elle est correcte à 100%.

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

Néanmoins, je suis se demandant s'il est possible d'obtenir quelque chose comme ça afin que nous ayons une réponse explicite pour les rôles qui ne sont pas attribués.

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');


0 commentaires

3 Réponses :


0
votes

Essayez la requête ci-dessous en espérant que cela vous aidera.

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


2 commentaires

Merci pour vos efforts et votre aide. Comme déjà mentionné dans un deuxième commentaire, la première requête a fait du bon travail pour moi.


Pas de soucis, méfiez-vous des requêtes OLAP - en particulier avec de grands ensembles de données. ROW_NUMBER () OVER (PARTITION BY ... ORDER BY ...) impliquera probablement une redistribution et impliquera absolument un tri. Si vous payez pour TPerf (utilisation du processeur), n'effectuez pas les fonctions OLAP sauf si vous devez le faire. Cela dit, dans ce cas, cela ne devrait pas être trop grave car les volumes seront faibles. Dans un exemple, j'ai comparé la fonction OLAP à plus de 3 fois les ressources d'une fonction non OLAP équivalente. Vous devez accepter et voter pour la réponse qui vous convient le mieux.



0
votes

Utilisez une jointure croisée pour générer les lignes, puis une jointure gauche pour introduire les valeurs.

Malheureusement, Teradata rend un peu difficile la génération du liste de rôles, mais cela devrait fonctionner:

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 commentaires

0
votes

Je n'ai pas accès à mon TD pour le moment, donc je le fais de mémoire:

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

j'espère qu'il n'y aura pas d'erreurs de syntaxe.

Fondamentalement, la requête interne produit une liste comme celle-ci:

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;

Ensuite, la requête externe sélectionne l'agrégat de chaque colonne. Nous faisons un max, donc "Oui" battra "Non". Vous n'obtiendrez un non que si l'utilisateur n'a pas le rôle.

Remarque: il y a une hypothèse que le bénéficiaire, GrantKind et RoleName sont tous les mêmes. Si ce n'est pas le cas, vous obtiendrez plusieurs enregistrements par bénéficiaire. J'ai dû omettre le "quand accordé" car ce sera probablement à des moments différents.


1 commentaires

Merci, requête assez intéressante aussi et je pense que cela peut fonctionner aussi. Néanmoins, j'ai trouvé le premier un peu mieux.