Il existe deux tableaux Tableau A et Tableau B. Ils contiennent les mêmes colonnes coût et article. Le tableau B contient la liste des articles et leurs coûts correspondants alors que le tableau A ne contient que la liste des articles.
Nous devons maintenant vérifier les articles du tableau A, s'ils sont présents dans le tableau B alors le coût de l'article correspondant doit être attribué au coût de l'article dans le tableau A.
Quelqu'un peut-il m'aider en écrivant une requête à ce sujet?
Considérez les tableaux comme suit:
Tableau A:
Table A: item cost pen 0 book 50 watch 1000
Tableau B:
item cost ------------- watch 1000 book 50
Résultat attendu
XXX
3 Réponses :
Ajoutez simplement une clé étrangère (clé primaire de la table A) dans la table B comme vous pouvez dire table A ID
puis ajoutez une jointure (une jointure droite peut être) dans la requête à obtenir ou à attribuer les prix des articles respectifs.
rejoindre
être comme
SELECT item, cost FROM tablename a RIGHT JOIN tablename b ON a.item= b.item;
Modifier:
Juste modifiez ce nom de table, exécutez-le maintenant.
Selon votre requête, nous ne pouvons pas attribuer le nom de l'article au coût. Cela génère une erreur et, en passant, select est d'afficher mais j'ai besoin que la valeur de coût soit attribuée aux éléments du tableau A du tableau B.
Il existe de nombreuses façons de le faire, si vous prenez la table b comme celle contenant le prix, une jointure externe gauche ferait l'affaire.
update table_a set cost = some_alias.cost from ( SELECT table_a.item, CASE WHEN table_b.cost IS NULL THEN 0 ELSE table_b.cost END as cost FROM table_a LEFT OUTER JOIN table_b ON table_a.item = table_b.item ) some_alias where table_a.item = some_alias.item
Le résultat aussi semble suggérer que le stylo qui n'est pas dans le tableau b devrait avoir un prix de 0 (c'est une mauvaise pratique) mais pour renvoyer le résultat souhaité, vous voudrez qu'une instruction case attribue une valeur si elle est nulle. p >
Afin de mettre à jour le tableau, selon le commentaire
SELECT table_a.item, CASE WHEN table_b.cost IS NULL THEN 0 ELSE table_b.cost END as cost FROM table_a LEFT OUTER JOIN table_b ON table_a.item = table_b.item
Merci! Cela fonctionne correctement. mais je veux que les valeurs soient attribuées aux éléments de la table A. ce qui ne se produit pas avec votre requête.
update table_a from -> sql query -> where item = query.item vous devriez pouvoir le prendre à partir de là
Cela ne fonctionne pas correctement. Toutes les valeurs de coût dans la table_a sont affectées à 0.
Cela sent beaucoup les devoirs mais par souci d'exhaustivité update table_a set cost = some_alias.cost from (SELECT table_a.item, CASE WHEN table_b.cost IS NULL THEN 0 ELSE table_b.cost END as cost FROM table_a LEFT OUTER JOIN table_b ON table_a.item = table_b.item) some_alias où table_a.item = some_alias.item
Je structurerais la mise à jour comme ceci:
with cost_data as ( select item, max (cost) filter (where item = 'watch') as watch, max (cost) filter (where item = 'book') as book from table_b group by item ) update table_a a set watch = c.watch, book = c.book from cost_data c where a.item = c.item and (a.watch is distinct from c.watch or a.book is distinct from c.book)
En substance, je fais une expression de table commune pour faire un tableau croisé dynamique d'un pauvre sur le tableau B pour obtenir les lignes en colonnes. Une mise en garde ici - s'il y a plusieurs coûts répertoriés pour le même article, cela peut ne pas faire ce que vous voulez, mais vous devrez alors savoir comment gérer cela dans presque tous les cas.
Alors je suis faire une "mise à jour A à partir de B" par rapport au CTE.
La dernière partie n'est pas critique, en soi, mais elle est utile - limiter la requête à ne s'exécuter que sur les lignes qui doivent changer. Il est préférable de limiter le DML s'il ne doit pas se produire (la meilleure façon d'optimiser quelque chose est de ne pas le faire).