0
votes

SQL: définir une valeur conditionnelle en fonction de critères variables dans une autre table

Un peu nouveau dans SQL - la base de données est Snowflake, qui, je crois, est ANSI

Tableau principal ci-dessous. Des combinaisons du même numéro / UPC / entrepôt / date peuvent être possibles, car un nouvel enregistrement est ajouté chaque fois qu'un nouveau problème est signalé. D'autres colonnes existent, mais ne devraient pas affecter cette question

 entrez la description de l'image ici

La colonne d'exclusion est ce que j'essaie de comprendre - elle doit être 'Y' si la combinaison souhaitée de Issue / UPC / Warehouse et Date se trouve dans le tableau d'exclusion, illustré ci-dessous.

 entrez la description de l'image ici

La partie la plus délicate est la colonne LEVEL, qui définit si une combinaison UPC / Issue / Warehouse doit correspondre, ou simplement UPC / Issue, ou simplement UPC. De plus, les enregistrements de la table principale doivent être compris dans la plage de dates pour être exclus.

Visuellement, le résultat attendu est le suivant

 entrez la description de l'image ici

Cette solution ne fonctionne que pour un seul niveau (Issue / UPC / Warehouse), mais je ne peux pas comprendre comment faire les deux autres sans chevauchement et la possibilité d'exclure des enregistrements en cas d'accident.

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


1 commentaires

votre cas d'utilisation est un peu compliqué, mais il semble que vous ayez juste besoin d'une déclaration de cas. Il y a beaucoup de documentation sur la façon de faire cela, et tout devrait s'appliquer à Snowflake


4 Réponses :


2
votes

Je ne suis pas ce que votre solution manque, mais vous pouvez gérer plusieurs situations / sorties différentes pour la colonne avec une instruction case. Seul le premier correspondant s'appliquera afin d'éviter les chevauchements.

Quelque chose comme ceci:

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
;

Vous pouvez également l'utiliser pour inverser votre logique et spécifier «N» situations et par défaut à «Y» si cela a plus de sens.


0 commentaires

0
votes

Je suis d'accord avec ce que David a dit, ce dont vous avez besoin est une mise à jour avec une déclaration de cas. Soyez un peu prudent avec l'instruction case - seuls les premiers critères remplis seront exécutés. donc codez d'abord pour le cas le plus courant, puis ensuite pour le cas le plus courant.


0 commentaires

2
votes

La réponse de David a couvert la bonne approche à adopter, en utilisant la CASE expression conditionnelle , mais assurez-vous que votre requête intègre également la vérification de niveau dans chaque condition explicitement. Voici un exemple détaillé:

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;


0 commentaires

1
votes

Si j'ignore la colonne level , alors je peux simplement utiliser null pour voir s'il y a une correspondance. Si cela suffit, alors:

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

Vous pouvez également utiliser la colonne level (je pense que ce qui précède est plus clair). Quelque chose comme ceci:

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


0 commentaires