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
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.
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
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);
4 Réponses :
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.
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.
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;
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 );
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