OVH Cloud OVH Cloud

[MYSQL4] aide sur une requête

1 réponse
Avatar
Bruno
Bonjour,
Je n'arrive pas à écrire une requête, pouvez vous m'aider ?

Voici le problème :
Pour un produit (identifié par ProdNum) j'ai plusieurs offres (identifié
par ArtNum) à des prix différents et provenant de fournisseurs
différents (identifié par FourNum).
Certaines de ces offres ont du stock, d'autre pas.

1 il faut que je sorte pour chaque produit l'offre la moins chère qui a
du stock. J'y suis arrivé (avec l'aide d' un membre du forum).
cela donne ceci :

select A1.* FROM test as A1, (SELECT ProdNum, MIN(Prix) MiniPrix FROM
test where Stock=1 GROUP BY ProdNum) as A2 WHERE A1.ProdNum=A2.ProdNum
AND A1.Prix=A2.MiniPrix

2 Maintenant il faut que je sorte pour chaque produit (QUI N'EST PAS
CONCERNÉ PAR LA PREMIÈRE REQUETE) l'offre la moins chère qui n'a pas de
stock.

JE N'Y ARRIVE PAS !!!!! (help)

NB. L'intersection entre l'ensemble des résultat de la requête 1 et de
la requête 2 doit être vide.
Par rapport à la table fournie (ci-dessous), la requête 1 donne
ArtNum appartient à {2,6}
La requête 2 ArtNum appartient à {3,5}


3 il faut que je réunisse ces deux requêtes en une seule pour pouvoir
faire des tris.
Je pense m'en sortir avec UNION.

La table :

CREATE TABLE test (
ArtNum tinyint(4) NOT NULL default '0',
ProdNum tinyint(4) NOT NULL default '0',
Stock tinyint(4) NOT NULL default '0',
Prix decimal(5,2) NOT NULL default '0.00',
FourNum tinyint(4) NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO test (ArtNum, ProdNum, Stock, Prix, FourNum) VALUES (1, 1,
1, 2.50, 1);
INSERT INTO test (ArtNum, ProdNum, Stock, Prix, FourNum) VALUES (3, 2,
0, 5.00, 1);
INSERT INTO test (ArtNum, ProdNum, Stock, Prix, FourNum) VALUES (5, 3,
0, 8.00, 1);
INSERT INTO test (ArtNum, ProdNum, Stock, Prix, FourNum) VALUES (7, 4,
0, 3.50, 2);
INSERT INTO test (ArtNum, ProdNum, Stock, Prix, FourNum) VALUES (2, 1,
1, 1.50, 2);
INSERT INTO test (ArtNum, ProdNum, Stock, Prix, FourNum) VALUES (4, 2,
0, 7.00, 2);
INSERT INTO test (ArtNum, ProdNum, Stock, Prix, FourNum) VALUES (6, 4,
1, 4.50, 4);

1 réponse

Avatar
Seb Hastien
Bruno a exprimé avec précision :
Bonjour,
Je n'arrive pas à écrire une requête, pouvez vous m'aider ?


Bonjour, on va essayer...


Voici le problème :
Pour un produit (identifié par ProdNum) j'ai plusieurs offres (identifié
par ArtNum) à des prix différents et provenant de fournisseurs
différents (identifié par FourNum).
Certaines de ces offres ont du stock, d'autre pas.

1 il faut que je sorte pour chaque produit l'offre la moins chère qui a
du stock. J'y suis arrivé (avec l'aide d' un membre du forum).
cela donne ceci :

select A1.* FROM test as A1, (SELECT ProdNum, MIN(Prix) MiniPrix FROM
test where Stock=1 GROUP BY ProdNum) as A2 WHERE A1.ProdNum¢.ProdNum
AND A1.Prix¢.MiniPrix

2 Maintenant il faut que je sorte pour chaque produit (QUI N'EST PAS
CONCERNÉ PAR LA PREMIÈRE REQUETE) l'offre la moins chère qui n'a pas de
stock.

JE N'Y ARRIVE PAS !!!!! (help)

NB. L'intersection entre l'ensemble des résultat de la requête 1 et de
la requête 2 doit être vide.
Par rapport à la table fournie (ci-dessous), la requête 1 donne
ArtNum appartient à {2,6}
La requête 2 ArtNum appartient à {3,5}



En fait au lieu de réfléchir en terme d'exclusion (càd de chercher
toutes les lignes qui ne font pas partie de la requête 1), il vaut
mieux chercher une condition qui trouve toutes ces lignes.
Ce que tu cherches à faire en fait c'est trouver par produit la ligne
avec un prix d'article minimum et ce, uniquement pour les produits pour
lesquels tous les articles ont un flag stock à 0.
Pour trouver toutes ces lignes en sql on peut faire une requête du
style
SELECT ProdNum FROM test GROUP BY ProdNum HAVING max(Stock)=0;
ou
SELECT T.ProdNum FROM (SELECT ProdNum, max(Stock) as MaxStock FROM
test) T WHERE T.MaxStock=0

Par conséquent la requête 2 que tu cherches à construire pourrait être
la suivante :

select A1.* FROM test as A1, (SELECT ProdNum, MIN(Prix) MiniPrix,
max(Stock) as MaxStock FROM
test GROUP BY ProdNum) as A2 WHERE A1.ProdNum¢.ProdNum
AND A1.Prix¢.MiniPrix
AND A2.MaxStock=0;

ou

select A1.* FROM test as A1, (SELECT ProdNum, MIN(Prix) MiniPrix,
max(Stock) as MaxStock FROM
test GROUP BY ProdNum HAVING MaxStock=0 ) as A2 WHERE
A1.ProdNum¢.ProdNum
AND A1.Prix¢.MiniPrix;

Je n'ai pas testé ces requêtes et elles restent bien sûr à vérifier, il
est tard et il se peut qu'il y ait quelques erreurs.
Si tu as beaucoup de volumétrie je pense que la 2eme requête doit être
plus efficace puisque la sous requête ramème moins de ligne mais je ne
connais pas bien MySQL alors je ne vais pas trop m'avancer sur les
perfs...



3 il faut que je réunisse ces deux requêtes en une seule pour pouvoir
faire des tris.
Je pense m'en sortir avec UNION.



Effectivement, cela devrait fonctionner

La table :

CREATE TABLE test (
ArtNum tinyint(4) NOT NULL default '0',
ProdNum tinyint(4) NOT NULL default '0',
Stock tinyint(4) NOT NULL default '0',
Prix decimal(5,2) NOT NULL default '0.00',
FourNum tinyint(4) NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO test (ArtNum, ProdNum, Stock, Prix, FourNum) VALUES (1, 1,
1, 2.50, 1);
INSERT INTO test (ArtNum, ProdNum, Stock, Prix, FourNum) VALUES (3, 2,
0, 5.00, 1);
INSERT INTO test (ArtNum, ProdNum, Stock, Prix, FourNum) VALUES (5, 3,
0, 8.00, 1);
INSERT INTO test (ArtNum, ProdNum, Stock, Prix, FourNum) VALUES (7, 4,
0, 3.50, 2);
INSERT INTO test (ArtNum, ProdNum, Stock, Prix, FourNum) VALUES (2, 1,
1, 1.50, 2);
INSERT INTO test (ArtNum, ProdNum, Stock, Prix, FourNum) VALUES (4, 2,
0, 7.00, 2);
INSERT INTO test (ArtNum, ProdNum, Stock, Prix, FourNum) VALUES (6, 4,
1, 4.50, 4);



--
L'homme qui tombe à pic