SELECT MIN() avec le bon identifiant

SELECT MIN() avec le bon identifiant - SQL/NoSQL - Programmation

Marsh Posté le 01-04-2011 à 05:51:16    

Bonjour tout le monde,
j'ai une table qui ressemble a ceci:

Code :
  1. produits
  2. id_produit | id_produit_ref | prix | reduction | ...
  3. 1001       |  10150         | 19.00   | 0
  4. 1001       |  10151         | 19.00   | 0
  5. 1001       |  10152         | 19.00   | 15
  6. 1002       |  10153         | 15.00   | 0
  7. 1002       |  10154         | 13.00   | 0
  8. ...


j'aimerais afficher la ligne qui contient le prix le plus bas mais AVEC SON identifiant. j'ai fait ceci:

Code :
  1. SELECT id_produit, id_produit_ref, MIN(prix) AS prix_original, MIN(prix * (1 - (reduction / 100))) AS prix FROM produits GROUP BY id_prod ORDER BY prix


La requete fonctionne bien, elle me retourne les resultats suivant:

Code :
  1. id_produit  id_produit_ref prix_original prix
  2. 1001  10150  19.00  16.150000
  3. 1002  10153  13.00  13.000000


mais j'aimerais qu'il me retourne l'id_produit_ref 10152 au lieu de 10150 et 10154 au lieu de 10153
 
Sauriez vous comment faire?
 
MErci infiniment

Reply

Marsh Posté le 01-04-2011 à 05:51:16   

Reply

Marsh Posté le 01-04-2011 à 10:19:27    

Essaye ca:

Code :
  1. SELECT a.id_produit, a.id_produit_ref, a.prix prix_original, b.prix_reduc prix
  2. FROM produits a
  3.     JOIN (
  4.         SELECT id_produit, MIN(prix * (1 - (reduction / 100.0))) prix_reduc
  5.         FROM produits
  6.         GROUP BY id_produit
  7.     ) b ON b.id_produit = a.id_produit AND b.prix_reduc = a.prix * (1 - (a.reduction / 100.0))

Message cité 1 fois
Message édité par Oliiii le 01-04-2011 à 10:20:04
Reply

Marsh Posté le 01-04-2011 à 11:24:42    

ou bien (pour mysql, à adapter suivant le SGBD)

Code :
  1. SELECT id_produit, id_produit_ref, prix AS prix_original, prix * (1-reduction/100) AS prix FROM produits ORDER BY prix ASC, reduction DESC LIMIT 1


Si tu as un index (prix ASC, reduction DESC), ta requête va directement chercher la valeur min dedans sans parcourir la table.

 

Lance un explain sur les différentes requêtes, ça devrait être flagrant ...


Message édité par Paulp le 01-04-2011 à 11:24:51
Reply

Marsh Posté le 01-04-2011 à 13:38:13    

Merci pour vos reponses.
Paulp: ta requete ne marchera pas dans mon cas car elle m'affichera qu'un seul produit, or il me faut afficher tout le catalogue...
 
Oliii: la requete marche bien, je vais la tester davantage et te tiendrai informé.
 
Merci pour tout

Reply

Marsh Posté le 01-04-2011 à 14:39:45    

Oliiii a écrit :

Essaye ca:

Code :
  1. SELECT a.id_produit, a.id_produit_ref, a.prix prix_original, b.prix_reduc prix
  2. FROM produits a
  3.     JOIN (
  4.         SELECT id_produit, MIN(prix * (1 - (reduction / 100.0))) prix_reduc
  5.         FROM produits
  6.         GROUP BY id_produit
  7.     ) b ON b.id_produit = a.id_produit AND b.prix_reduc = a.prix * (1 - (a.reduction / 100.0))



La requete fonctionne parfaitement mais j'ai un peu de mal a l'adopter a mes besoins :(
voici ma requete initiale simplifiee:

Code :
  1. SELECT p.id_prod, p.id_theme, pr.id_prod_ref, pr.stock, MIN(pr.price) AS price_org, MIN(pr.price * (1 - (pr.discount / 100))) AS price, pr.discount, pt.title, av.attr_val AS material
  2. FROM products_references AS pr
  3. INNER JOIN products AS p ON pr.id_prod = p.id_prod
  4. INNER JOIN products_info_trans AS pt ON p.id_prod = pt.id_prod
  5. INNER JOIN products_ref_vars AS pv ON pr.id_prod_ref = pv.id_prod_ref
  6. INNER JOIN attributes_values AS av ON pv.id_attr_val = av.id_attr_val
  7. WHERE p.id_cat = $id_cat
  8. AND p.active = 'y'
  9. AND pt.lang_iso = '$lang_iso'
  10. AND av.id_attr = 109
  11. GROUP BY pr.id_prod, material
  12. ORDER BY price


 
comment integreras tu ta requete sachant que je regroupe les produits par identifiant et par matiere??

Reply

Marsh Posté le 04-04-2011 à 08:43:43    

L'idée c'est de faire un sous select qui sort le prix minimum et suffisement d'info pour retrouver l'enregistrement dans la table (id_produit dans mon cas).
 
C'est le meme principe dans ton 2eme exemple mais au lieu d'avoir une seule table dans le sous select, tu auras aussi tout les joins et le where.
 
C'est difficil de t'aider plus sans un exemple concret des données et de la structure des tables.


Message édité par Oliiii le 04-04-2011 à 08:44:14
Reply

Marsh Posté le 04-04-2011 à 12:58:46    

OK, merci beaucoup ;) ca l'air de marcher :)
A bientot

Reply

Marsh Posté le 07-04-2011 à 17:18:51    

Hello,
J'ai détecter un cas ou la requête ne marchera pas bien :D

Code :
  1. id_prod | id_prod_ref | prix | reduc
  2. 1001 | 10015 | 13.50 | 0
  3. 1001 | 10017 | 15.00 | 10


la requête me retournera 2 fois 1001 car le prix final est le même!
La solution que j'ai trouvé est de rajouter un GROUP BY id_prod a la fin, mais est ce bon?
 
J'aurais encore 1 toute petite question svp:
Concernant les commandes, je prévois 2 tables:
1- commandes (id_commande, id_client, frais_livraison, date, ...)
2- commandes_details (id_commande, id_prod_ref, quantite, prix, reduction)
 
Dois-je rajouter un champ prix_total dans la table commande ou devrais je plutôt le récupérer avec un SUM() sur la table commande_details??
Pareil sur la table commandes_details, dois je mettre un champ prix_reduction ou plutôt le calculer a partir des champs prix et reduction??
 
Merci

Reply

Marsh Posté le 08-04-2011 à 09:01:20    

Sauf si tu as un probleme de performance, il ne faut pas mettre de colonne qui peuvent etre calculée a partir d'autre colonne (ca implique une maintenance et un risque de casser l'integrité de la DB).

Reply

Marsh Posté le 08-04-2011 à 17:39:57    

Oliiii a écrit :

Sauf si tu as un probleme de performance, il ne faut pas mettre de colonne qui peuvent etre calculée a partir d'autre colonne (ca implique une maintenance et un risque de casser l'integrité de la DB).


ah!! je ne sais toujours pas quoi faire alors, je ne pourrai pas savoir si je serai confronté a des problemes de performance!! que ferais tu a ma place? je suis en mutualisé Pro chez 1 and 1
 
et sinon concernant ma 1ere question au sujet de la requete, que faut il faire?

Reply

Marsh Posté le 08-04-2011 à 17:39:57   

Reply

Marsh Posté le 08-04-2011 à 17:54:29    

http://dev.mysql.com/doc/refman/5. [...] p-row.html
 
Dans ce cas, il faudra à mon avis stocker (et même indexer) le prix après réduction.
 
Pour les problèmes de performance, tu le vois à l'utilisation. Si une page met plus d'1s à charger, tu analyses pourquoi et tu résouds le problème.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed