web-dev-qa-db-fra.com

SUM (DISTINCT) Basé sur d'autres colonnes

J'ai actuellement une table qui ressemble à ceci:

+------+-------+------------+------------+
| id   | rate  | first_name | last_name  |
+------+-------+------------+------------+

Ce que je dois faire, c'est obtenir le SUM de la colonne des taux, mais une seule fois pour chaque nom. Par exemple, j'ai trois lignes de nom John Doe, chacune avec un taux 8. J'ai besoin que le SUM de ces lignes soit 8, pas 24, donc il compte le taux une fois pour chaque groupe de noms.

SUM(DISTINCT last_name, first_name) ne fonctionnerait pas, bien sûr, car j'essaie de résumer la colonne de taux, pas les noms. Je sais qu'en comptant des enregistrements individuels, je peux utiliser COUNT(DISTINCT last_name, first_name), et c'est le type de comportement que j'essaie d'obtenir de SUM.

Comment puis-je obtenir seulement SUM un tarif pour chaque nom?

Merci d'avance!

18
David
select sum (rate)
from yourTable
group by first_name, last_name

Modifier

Si vous voulez obtenir toute la somme de ces petits "sums", vous obtiendrez une somme de toutes les tables ..

Select sum(rate) from YourTable

mais si, pour une raison quelconque, les différences (si vous utilisez un where, par exemple) et que vous avez besoin d'une somme pour cette sélection ci-dessus, faites-le.

select sum(SumGrouped) from 
(    select sum (rate) as 'SumGrouped'
    from yourTable
    group by first_name, last_name) T1
10
Gonzalo.-

David a dit avoir trouvé sa réponse comme telle:

SELECT SUM(rate) FROM (SELECT * FROM records GROUP BY last_name, first_name) T1

Mais quand vous faites le GROUP BY Dans la requête interne, je pense que vous devez utiliser des fonctions d'agrégation dans votre SELECT. Donc, je pense que la réponse est plus comme:

SELECT SUM(rate) FROM (SELECT MAX(rate) AS rate FROM records GROUP BY last_name, first_name) T1

J'ai choisi MAX() pour choisir un seul "taux" pour une combinaison "last_name, first_name" mais MIN() devrait fonctionner de la même façon, en supposant que "last_name, first_name" nous mène toujours à la même "taux" même lorsqu'il se produit plusieurs fois dans le tableau. Cela semble être l'hypothèse originale de David - que pour un nom unique, nous voulons saisir le taux une seule fois parce que nous savons que ce sera le même.

6
Georgy Vladimirov
SELECT SUM(rate)
FROM [TABLE] 
GROUP BY first_name, last_name;
2
Vasil Nikolov
SELECT SUM(rate)
FROM [TABLE] 
GROUP BY CONCAT_WS(' ', first_name, last_name);
1
MetalFrog

Vous pouvez utiliser l'un des exemples de code ci-dessus fournis, car avec la clause group by sans fonction d'agrégation, un enregistrement indéterminé sera renvoyé pour chaque condition de regroupement. Vous pouvez vous référer http://dev.mysql.com/doc/refman/5.5/en/group-by-hidden-columns.html lien pour une lecture plus approfondie.

0
Manisha Mahawar

Vous pouvez le faire en distinguant les valeurs que vous additionnez. C'est possible mais c'est très très moche.

Tout d'abord, vous pouvez transformer une chaîne en nombre en prenant un hachage. Le SQL ci-dessous fait un hachage MD5 du prénom et du nom, qui renvoie 32 chiffres hexadécimaux. SUBSTRING prend les 8 premiers d'entre eux, et CONV le transforme en un nombre à 10 chiffres (il est théoriquement possible que ce ne soit pas unique):

CONV(SUBSTRING(MD5(CONCAT(first_name,last_name)), 1, 8), 16, 10)

Ensuite, vous divisez cela par un très grand nombre et l'ajoutez au taux. Vous vous retrouverez avec un taux comme 8,0000019351087950. Vous devez utiliser FORMAT pour éviter que MySQL tronque les décimales. Ce tarif sera désormais unique pour chaque prénom et nom.

FORMAT(rate + CONV(SUBSTRING(MD5(CONCAT(first_name,last_name)), 1, 8), 16, 10)/1000000000000000, 16)

Et puis si vous faites la SOMME DISTINCTE dessus, elle ne comptera les 8 qu'une fois. Ensuite, vous devez PLANCHER le résultat pour vous débarrasser des décimales supplémentaires:

FLOOR(SUM(DISTINCT FORMAT(rate + CONV(SUBSTRING(MD5(CONCAT(first_name,last_name)), 1, 8), 16, 10)/1000000000000000, 16)))

J'ai trouvé cette approche en faisant une requête beaucoup plus compliquée qui a joint et groupé plusieurs tables. Je ne sais toujours pas si je vais l'utiliser car c'est assez horrible, mais ça marche. Il est également 6 ans trop tard pour être utile à la personne qui a répondu à la question.

0
Paul