J'ai donc:
min(A.id) SUM(A.amount) COUNT(B.id) 1 50 3 3 10 0
Je lance cette requête:
min(A.id) SUM(A.amount) COUNT(B.id) 1 75 3 3 10 0
J'obtiens:
SELECT min(A.id), SUM(A.amount), COUNT(B.id) FROM A LEFT JOIN B ON A.id = B.A_id GROUP BY A.type
3 Réponses :
une façon de faire cela serait d'utiliser ROW_NUMBER()
:
WITH CTE AS (SELECT A.id AS Aid, A.[type], A.amount, B.id AS bid, txt, ROW_NUMBER() OVER (PARTITION BY A.id ORDER BY B.id) AS RN FROM A LEFT JOIN B ON A.id = B.A_ID) SELECT MIN(Aid) AS Min_A_ID, SUM(CASE RN WHEN 1 THEN amount END) AS Amount, COUNT(bid) AS BCount FROM CTE GROUP BY [type];
Je recommande également de se débarrasser de ce type de données text
et en utilisant varchar(MAX)
.
Cela peut se produire lorsque vous faites une somme à partir d'une relation 1-N.
Les enregistrements correspondants peuvent multiplier le résultat.
Par exemple, quand 1 enregistrements dans A sont joints avec 2 dans B, il retourne 2 fois la quantité de A avant le GROUP BY. Donc, un SUM double alors A.amount.
Un moyen de contourner qui consiste à utiliser des sous-requêtes qui rejoignent un à un.
Et un COUNT DISTINCT peut être utilisé pour compter les identifiants uniques.
C'est donc juste un moyen d'obtenir la SOMME de A correcte.
SELECT q1.type, q1.min_id, q2.amount, COALESCE(q1.totalB, 0) as totalB FROM ( SELECT A.type, MIN(A.id) AS min_id, COUNT(DISTINCT B.id) AS totalB FROM A LEFT JOIN B ON B.A_id = A.id GROUP BY A.type ) AS q1 JOIN ( SELECT type, SUM(amount) AS amount FROM A GROUP BY type ) AS q2 ON q2.type = q1.type
Le SQL est testé pour MySql. Mais c'est un SQL standard ANSI qui fonctionnerait sur presque tous les SGBDR, y compris MS Sql Server.
Juste une version plus courte de la solution. Il compte les B_ID en premier dans la requête interne, je dois donc faire la somme des comptes dans la requête externe.
SELECT min(A.id), SUM(A.amount), Sum(Bid) FROM A LEFT JOIN (select count(id) as Bid, A_id from B group by A_id) as Bcount ON A.id = Bcount.A_id GROUP BY A.type
Veuillez marquer uniquement le SGBD que vous utilisez.
Lorsque vous faites votre jointure, vous avez deux lignes dans tableb qui ont un type de 1. Vous obtenez donc toutes les lignes dans tablea avec le type a pour CHAQUE ligne dans tableb. Retirez l'agrégation et vous verrez les lignes renvoyées.
Exécutez la requête sans aucune agrégation ... db-fiddle.com/f/sAqaUyG1E9rHyqsXkoF2pz/0 Voir. Maintenant, il est évident pourquoi vous obtenez ce résultat
SUM
ne fait pas la somme des lignes distinctes, il additionne toutes les lignes de ce groupe. EssayezSELECT * FROM A LEFT JOIN B ON A.id = B.A_id WHERE a.type = 0;
et vous verrez que vous obtenez 3 lignes avec la valeur25
pourmontant
, et3 * 25 = 75
pas50
.merci @larnu je suis conscient de la manière d'y parvenir
SQL Server et MySQL sont des produits complètement différents. Lequel est-ce ???
son propos de sql-server (mysql a été supprimé mis à jour), quel est le moyen d'obtenir 50 et 3 ou ce n'est pas possible?
Le résultat obtenu est correct, vous avez 2 fois A_ID = 1 et un pour A_ID = 2 .. 2x25 +25
Dans SQL Server, cela est simple à contourner. Dans MySQL 5.7, vous n'avez pas de chance, j'en ai peur. Je veux dire que tu "pourrais" probablement le faire, mais ça va être douloureux au mieux.
@all oui le résultat est correct ma question est: comment puis-je obtenir mon résultat attendu s'il vous plaît?