1
votes

multiplier les champs en fonction d'une valeur de champ en sql

J'ai ce genre de tableau:

name,final
a,30
b,150
c,500

MODIFIER

Ma table est comme ça et j'aurai toujours deux lignes avec le même valeur dans le champ name:

Ma table

et je voudrais multiplier les lignes ayant la même valeur sur nom , donc obtenir quelque chose comme ceci:

name,code1,code2
a,3,
b,5,
c,10,
a,,10
b,,30
c,,50

Je pensais aussi transformer le tableau précédent en celui-ci: entrez la description de l'image ici

sql

3 commentaires

Voulez-vous toujours plusieurs valeurs de code1 avec des valeurs de code2 ? Et si vous avez trois lignes pour le même nom (au lieu de deux) - quel devrait être le résultat alors? Je ne sais pas non plus ce que signifie le , dans les exemples de données. Ces lignes n'ont-elles aucune valeur pour code1 ? Et s'ils ont une valeur? Que voulez-vous multiplier alors?


@a_horse_with_no_name ma table est comme celle montrée dans l'exemple, j'aurai toujours deux lignes pour le même nom. et , signifie que le code1 est manquant


Dans le résultat final, vous vouliez mettre a, 300 et c, 400 , non?


3 Réponses :


1
votes

Essayez ce qui suit -

select name, min(code1)*min(code2) as final
from tablename
group by name


3 commentaires

cette solution fonctionne, mais pas toujours je ne comprends pas pourquoi


@stackfac, pouvez-vous me montrer dans quel cas cela ne fonctionne pas


désolé cela fonctionne correctement, mais j'ai dû changer le type d'entier en long. Merci!



0
votes

SQL n'a pas de fonction d'agrégation "produit" intégrée. Mais vous pouvez revenir à l'arithmétique et utiliser les logarithmes pour cela. La syntaxe exacte peut varier selon la base de données, mais l'idée est:

select name, exp(sum(ln(code1))) as product
from t
group by name;

Tous vos exemples sont positifs. Cela devient un peu plus compliqué si vous devez gérer des valeurs négatives ou nulles.


3 commentaires

puis-je simplement transformer le tableau en: nom, code1, code2 a, 3,10 b, 5,150


@stackfac. . . Je ne comprends pas votre commentaire. Cela renvoie les données comme décrit par la question. Ce n'est pas une bonne idée de transformer les tables en place, mais vous pouvez enregistrer les résultats dans une nouvelle table si vous le souhaitez.


@GordonLinoff: Je pense que code1 devrait être multiplié par code2 mais les exemples de données sont un peu déroutants



2
votes

Si vous toujours avez deux lignes pour chaque nom où l'une (seulement) a une valeur pour code1 et l'autre (seulement) a une valeur pour code2, vous pouvez utiliser une auto-jointure

select t1.name, t1.code1, t2.code2, t1.code1 * t2.code2
from the_table t1 
  join the_table t2 on t1.name = t2.name and t2.code1 is null
where t1.code2 is null;


4 commentaires

c'est un peu plus délicat que cela, car j'utilise un graphdb. Merci quand même!


Alors pourquoi avez-vous tagué votre question avec postgresql ?


parce que je pensais que c'était une chose facile et je pensais aussi que taguer avec le bon tag, personne n'allait m'aider


Eh bien, j'étais sur le point de publier une réponse sur la façon de créer un agrégat personnalisé dans Postgres - cela ne vous aurait pas aidé du tout à l'époque. Vous ne devriez jamais marquer vos questions avec des choses sans rapport. Ma requête devrait fonctionner comme la réponse acceptée - si ce n'est pas le cas, ce "graphdb" a une implémentation SQL vraiment médiocre.