Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

PostgreSQL Somme groupée

16 réponses
Avatar
Etienne
Salut.

j'ai une table du style

CREATE TABLE "matable" (
"idclient" integer,
"refproduit" text,
"ca" integer,
PRIMARY key (idclient, idproduit)
);


Comment puis faire pour avoir pour chaque client le ca généré par les 3
principaux produit.

supponsons que la table soit remplie ainsi

idclient, refproduit, ca
1, A, 10
1, B, 20
1, C, 30
1, D, 40
1, E, 50
1, A, 30
1, C, 50
1, D, 50
1, E, 10

J'aimerai avoir au final
1, 120
2, 130

a savoir
pour le client 1 la somme 30 + 40 + 50 correspondant aux 3 produits
qu'il a le plus commandé (C, D, E)
pour le client 2 la somme 30 + 50 + 50 correspondant aux 3 produits
qu'il a le plus commandé (A, C, D)

Peut on faire ca en une seule requête ?
par ce que pour un client bien précis j'y arrive

SELECT idclient, sum(ca) FROM (SELECT idclient, ca FROM matable WHERE
idclient = 1 ORDER BY ca DESC LIMIT 3) as foo;

me donne ce que je veux pour le client 1 !!!

merci
Etienne.

6 réponses

1 2
Avatar
Etienne
Le 28/05/2012 23:32, SQLpro a écrit :
Quelque chose comme :

WITH T AS
(SELECT idclient, refproduit, SUM(ca) AS CA,
RANK() OVER(ORDER BY SUM(ca) DESC) AS N
FROM matable
GROUP BY idClient, refproduit)
SELECT idclient, refproduit, CA
FROM T
WHERE N <= 3;



Nan.
Ca donne pas le résultat voulu.

Ca trie bien, mais il n'existe pas pour chaque idclient un
enregistrement pour lequel N vaut 1 par exemple.

Etienne
Avatar
SQLpro
Le 29/05/2012 14:29, Etienne a écrit :
Le 28/05/2012 23:32, SQLpro a écrit :
Quelque chose comme :

WITH T AS
(SELECT idclient, refproduit, SUM(ca) AS CA,
RANK() OVER(ORDER BY SUM(ca) DESC) AS N
FROM matable
GROUP BY idClient, refproduit)
SELECT idclient, refproduit, CA
FROM T
WHERE N <= 3;



Nan.
Ca donne pas le résultat voulu.

Ca trie bien, mais il n'existe pas pour chaque idclient un
enregistrement pour lequel N vaut 1 par exemple.

Etienne



CREATE TABLE matable (
idclient integer,
refproduit varchar(16),
ca integer
);

INSERT INTO matable VALUES
(1, 'A', 10),
(1, 'B', 20),
(1, 'C', 30),
(1, 'D', 40),
(1, 'E', 50),
(2, 'A', 30),
(2, 'C', 50),
(2, 'D', 50),
(2, 'E', 10);

WITH T AS
(SELECT idclient, ca,
RANK() OVER(PARTITION BY idclient ORDER BY ca DESC) AS N
FROM matable)
SELECT idclient, SUM(ca) AS CA
FROM T
WHERE N <= 3
GROUP BY idclient;

idclient CA
----------- -----------
1 120
2 130

A +


--
Frédéric BROUARD - expert SGBDR et SQL - MVP SQL Server - 06 11 86 40 66
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Enseignant Arts & Métiers PACA, ISEN Toulon et CESI/EXIA Aix en Provence
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
*********************** http://www.sqlspot.com *************************
Avatar
Alain Montfranc
Joli (je garde) mais ne marchera pas si on a des produits ex-aequos
(par exemple 4 CA identiques) car ils seront tous 4 classés en rang 1
Avatar
Etienne
Le 31/05/2012 09:35, SQLpro a écrit :
CREATE TABLE matable (
idclient integer,
refproduit varchar(16),
ca integer
);

INSERT INTO matable VALUES
(1, 'A', 10),
(1, 'B', 20),
(1, 'C', 30),
(1, 'D', 40),
(1, 'E', 50),
(2, 'A', 30),
(2, 'C', 50),
(2, 'D', 50),
(2, 'E', 10);

WITH T AS
(SELECT idclient, ca,
RANK() OVER(PARTITION BY idclient ORDER BY ca DESC) AS N
FROM matable)
SELECT idclient, SUM(ca) AS CA
FROM T
WHERE N <= 3
GROUP BY idclient;

idclient CA
----------- -----------
1 120
2 130

A +



Ah ben cette fois ca marche nickel !!!
c'est a cause du PARTITION sans doute. Faut que je regarde ce que fait
ce mot clé !!

Merci
Etienne
Avatar
Alain Montfranc
Dans son message précédent, Etienne a écrit :
Le 31/05/2012 09:35, SQLpro a écrit :
CREATE TABLE matable (
idclient integer,
refproduit varchar(16),
ca integer
);

INSERT INTO matable VALUES
(1, 'A', 10),
(1, 'B', 20),
(1, 'C', 30),
(1, 'D', 40),
(1, 'E', 50),
(2, 'A', 30),
(2, 'C', 50),
(2, 'D', 50),
(2, 'E', 10);

WITH T AS
(SELECT idclient, ca,
RANK() OVER(PARTITION BY idclient ORDER BY ca DESC) AS N
FROM matable)
SELECT idclient, SUM(ca) AS CA
FROM T
WHERE N <= 3
GROUP BY idclient;

idclient CA
----------- -----------
1 120
2 130

A +



Ah ben cette fois ca marche nickel !!!
c'est a cause du PARTITION sans doute. Faut que je regarde ce que fait ce mot
clé !!

Merci
Etienne



Attention : ca bugge si tu as des exaequos
Avatar
SQLpro
Le 31/05/2012 17:27, Alain Montfranc a écrit :
Dans son message précédent, Etienne a écrit :
Le 31/05/2012 09:35, SQLpro a écrit :
CREATE TABLE matable (
idclient integer,
refproduit varchar(16),
ca integer
);

INSERT INTO matable VALUES
(1, 'A', 10),
(1, 'B', 20),
(1, 'C', 30),
(1, 'D', 40),
(1, 'E', 50),
(2, 'A', 30),
(2, 'C', 50),
(2, 'D', 50),
(2, 'E', 10);

WITH T AS
(SELECT idclient, ca,
RANK() OVER(PARTITION BY idclient ORDER BY ca DESC) AS N
FROM matable)
SELECT idclient, SUM(ca) AS CA
FROM T
WHERE N <= 3
GROUP BY idclient;

idclient CA
----------- -----------
1 120
2 130

A +



Ah ben cette fois ca marche nickel !!!
c'est a cause du PARTITION sans doute. Faut que je regarde ce que fait
ce mot clé !!

Merci
Etienne



Attention : ca bugge si tu as des exaequos






Dans ce cas vous pouvez utiliser ROW_NUMBER().
Si vous voulez des exaequo "dense", DENSE_RANK() au lieu de RANK

A +

--
Frédéric BROUARD - expert SGBDR et SQL - MVP SQL Server - 06 11 86 40 66
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Enseignant Arts & Métiers PACA, ISEN Toulon et CESI/EXIA Aix en Provence
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
*********************** http://www.sqlspot.com *************************
1 2