Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 22/04/2011, 17h06   #1
Membre du Club
 
Homme Stéphane
Développeur Web
Inscription : septembre 2005
Messages : 100
Détails du profil
Informations personnelles :
Nom : Homme Stéphane
Âge : 37
Localisation : France, Ille et Vilaine (Bretagne)

Informations professionnelles :
Activité : Développeur Web
Secteur : Services à domicile

Informations forums :
Inscription : septembre 2005
Messages : 100
Points : 45
Points : 45
Envoyer un message via MSN à Shiva
Par défaut Récupérer le bon tarif

Bonjour,
J'ai un souci concernant la formulation d'une requete. Celle-ci doit me retourner un montant bien précis qui provient d'une table "tarifs" pour un produit donné.
Ma table a les champs suivants :
Code :
1
2
3
4
5
6
7
8
+------------+-------+----------+
| id_produit | prix  | quantite |
+------------+-------+----------+
|          1 | 10.00 |        1 |
|          1 |  8.00 |        5 |
|          1 |  6.00 |       10 |
|          1 |  4.00 |       15 |
+------------+-------+----------+
Dnas ma table panier j'ai une quantité commandée de 6 pour l'article avec l'id_produit = 1, or je n'arrive qu'a récupérer les tarifs à "6.00" et "4.00"
avec la requête ci-dessous :
Code :
1
2
3
4
SELECT t.prix, t.quantite
FROM panier AS p
LEFT JOIN tarifs AS t ON p.id_produit = t.id_produit
WHERE t.quantite >= p.quantite;
Vous me direz que ce comportement est normal vu que j'utilise '>=' mais dans ce cas comment récupérer la ligne avec le tarif = à "8.00"
Cela pet-il se faire en SQL ou dois-je récupérer toutes les lignes de tarifs pour le produits et passer ensuite avec un triage au niveau du PHP ?

Merci de votre aide.
Shiva est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/04/2011, 17h39   #2
Membre Expert
 
Homme
Responsable de service informatique
Inscription : janvier 2009
Messages : 1 081
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Responsable de service informatique
Secteur : Boutique - Magasin

Informations forums :
Inscription : janvier 2009
Messages : 1 081
Points : 1 875
Points : 1 875
Bonjour,
Je pense que la réponse est dans la question:
Citation:
Envoyé par Shiva Voir le message
Vous me direz que ce comportement est normal vu que j'utilise '>='
Le résultat correspond parfaitement à la requête. Tu demandes les lignes dont la quantité est >= à 6, le moteur renvoie toutes les lignes dont la quantité est >= 6...
Donc je me mets à la place de la base:
Qu'est-ce qui fait que tu veux récupérer le prix à 8.00 ? Quels critères doit-elle remplir pour que je la renvoie ?

Tatayo.

P.S. Petite remarque:
Code SQL :
1
2
3
4
SELECT t.prix, t.quantite
FROM panier AS p
LEFT JOIN tarifs AS t ON p.id_produit = t.id_produit
WHERE t.quantite >= p.quantite;

Vu que tu as un critère sur t dans le where, la jointure externe se transforme en jointure interne ! Il faut déplacer la condition dans la jointure:
Code SQL :
1
2
3
SELECT t.prix, t.quantite
FROM panier AS p
LEFT JOIN tarifs AS t ON p.id_produit = t.id_produit AND t.quantite >= p.quantite;
tatayo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/04/2011, 19h21   #3
Membre du Club
 
Homme Stéphane
Développeur Web
Inscription : septembre 2005
Messages : 100
Détails du profil
Informations personnelles :
Nom : Homme Stéphane
Âge : 37
Localisation : France, Ille et Vilaine (Bretagne)

Informations professionnelles :
Activité : Développeur Web
Secteur : Services à domicile

Informations forums :
Inscription : septembre 2005
Messages : 100
Points : 45
Points : 45
Envoyer un message via MSN à Shiva
Il faut savoir que l'exemple que je donne avec les quantités (et les prix) n'est pas fixe, donc à la place de 1, 5, 10 et 15 je pourrais très bien avoir 1, 10, 30, 50. Sinon, je viens de tester avec cette requête :
Code :
1
2
3
SELECT t.prix, MAX(t.quantite)
FROM panier AS p
LEFT JOIN tarifs AS t ON p.id_produit = t.id_produit AND t.quantite <= p.quantite;
Le résultat obtenu est bon mais est-ce correctement écrit ? Il y a peut-être une autre manière de faire ?

--> Non en fait cette requête n'est pas bonne du tout, retour case départ...
__________________
Stéphane
http://photos.nazgul.fr
Shiva est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/04/2011, 21h17   #4
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 442
Points : 10 442
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Si le prix est toujours dégressif avec l'augmentation de quantité, vous pouvez écrire ceci je pense :
Code :
1
2
3
4
5
6
  SELECT p.id_produit, p.quantite, COALESCE(MAX(t.prix), 0) AS prix
    FROM panier AS p
         LEFT OUTER JOIN tarifs AS t
           ON t.id_produit = p.id_produit
          AND t.quantite  >= p.quantite
GROUP BY p.id_produit, p.quantite
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/04/2011, 22h56   #5
Membre du Club
 
Homme Stéphane
Développeur Web
Inscription : septembre 2005
Messages : 100
Détails du profil
Informations personnelles :
Nom : Homme Stéphane
Âge : 37
Localisation : France, Ille et Vilaine (Bretagne)

Informations professionnelles :
Activité : Développeur Web
Secteur : Services à domicile

Informations forums :
Inscription : septembre 2005
Messages : 100
Points : 45
Points : 45
Envoyer un message via MSN à Shiva
Citation:
Envoyé par Waldar Voir le message
Si le prix est toujours dégressif avec l'augmentation de quantité, vous pouvez écrire ceci je pense :
Code :
1
2
3
4
5
6
  SELECT p.id_produit, p.quantite, COALESCE(MAX(t.prix), 0) AS prix
    FROM panier AS p
         LEFT OUTER JOIN tarifs AS t
           ON t.id_produit = p.id_produit
          AND t.quantite  >= p.quantite
GROUP BY p.id_produit, p.quantite
En fait non ça ne ramène pas la bonne ligne. Le prix retourné est "6.00". Celui-ci n'est pris en compte que si le nombre d'articles dans le panier est >= à 10.
__________________
Stéphane
http://photos.nazgul.fr
Shiva est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/04/2011, 23h01   #6
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 953
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 953
Points : 17 773
Points : 17 773
Utilisez une vue, ce sera plus facile... En principe on devrait toujours développer les application à partir de vues et non directement sur des tables .

Démonstration :

Code :
1
2
3
4
5
6
CREATE TABLE T_TARIF
(id_produit   INT NOT  NULL,
 quantite     INT NOT NULL,
 prix         DECIMAL(16,2) NOT NULL,
 CONSTRAINT PK_TRF PRIMARY KEY (id_produit, quantite));
GO
Code :
1
2
3
4
5
6
INSERT INTO T_TARIF 
VALUES (1, 1,  10.00),
(1,  5, 8.00),
(1, 10 , 6.00), 
(1, 15, 4.00);
GO
Code :
1
2
3
4
5
6
7
8
CREATE VIEW V_TARIF
AS
SELECT id_produit, quantite AS quantie_min,
       COALESCE((SELECT MIN(quantite) - 1
                 FROM   T_TARIF
                 WHERE  quantite > T.quantite), 2000000000) AS quantite_max,
       prix 
FROM   T_TARIF AS T
Code :
1
2
3
4
5
6
7
 
id_produit  quantie_min quantite_max prix
----------- ----------- ------------ ----------
1           1           4            10.00
1           5           9            8.00
1           10          14           6.00
1           15          2000000000   4.00
Dès lors les requêtes sur la vue deviennent triviales :

Code :
1
2
3
4
5
6
SELECT p.id_produit, p.quantite, prix
FROM   panier AS p
       INNER JOIN V_TARIF AS T
             ON p.id_produit = T.id_produit
                AND P.quantite BETWEEN T.quantie_min 
                                   AND T.quantie_mAX;
A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 23/04/2011, 02h13   #7
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 442
Points : 10 442
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Citation:
Envoyé par Shiva Voir le message
En fait non ça ne ramène pas la bonne ligne. Le prix retourné est "6.00". Celui-ci n'est prit en compte que si le nombre d'articles dans le panier est >= à 10.
Ok, par contre que ça ne vous empêche pas de réfléchir, dans ce cas il suffit d'inverser la solution :
Code :
1
2
3
4
5
6
 SELECT p.id_produit, p.quantite, COALESCE(MIN(t.prix), 0) AS prix
    FROM panier AS p
         LEFT OUTER JOIN tarifs AS t
           ON t.id_produit = p.id_produit
          AND t.quantite  <= p.quantite
GROUP BY p.id_produit, p.quantite
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 23/04/2011, 11h43   #8
Membre du Club
 
Homme Stéphane
Développeur Web
Inscription : septembre 2005
Messages : 100
Détails du profil
Informations personnelles :
Nom : Homme Stéphane
Âge : 37
Localisation : France, Ille et Vilaine (Bretagne)

Informations professionnelles :
Activité : Développeur Web
Secteur : Services à domicile

Informations forums :
Inscription : septembre 2005
Messages : 100
Points : 45
Points : 45
Envoyer un message via MSN à Shiva
Citation:
Envoyé par Waldar Voir le message
Ok, par contre que ça ne vous empêche pas de réfléchir, dans ce cas il suffit d'inverser la solution :
Code :
1
2
3
4
5
6
 SELECT p.id_produit, p.quantite, COALESCE(MIN(t.prix), 0) AS prix
    FROM panier AS p
         LEFT OUTER JOIN tarifs AS t
           ON t.id_produit = p.id_produit
          AND t.quantite  <= p.quantite
GROUP BY p.id_produit, p.quantite
C'est justement ce que j'ai tenté au début mais le résultat était prévisible, c'est la première lignes de tarifs qui est retournée => "10.00"
__________________
Stéphane
http://photos.nazgul.fr
Shiva est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/04/2011, 12h09   #9
Membre du Club
 
Homme Stéphane
Développeur Web
Inscription : septembre 2005
Messages : 100
Détails du profil
Informations personnelles :
Nom : Homme Stéphane
Âge : 37
Localisation : France, Ille et Vilaine (Bretagne)

Informations professionnelles :
Activité : Développeur Web
Secteur : Services à domicile

Informations forums :
Inscription : septembre 2005
Messages : 100
Points : 45
Points : 45
Envoyer un message via MSN à Shiva
Citation:
Code :
1
2
3
4
5
6
7
8
CREATE VIEW V_TARIF
AS
SELECT id_produit, quantite AS quantie_min,
       COALESCE((SELECT MIN(quantite) - 1
                 FROM   T_TARIF
                 WHERE  quantite > T.quantite), 2000000000) AS quantite_max,
       prix 
FROM   T_TARIF AS T
Merci pour cette idée de bosser directement sur une vue, c'est ce que je vais faire par conter je n'ai pas précisé que j'utilise mysql et la requête de création de vue fonctionne mais un select me retourne ceci :
Code :
1
2
3
4
5
6
id_produit  quantie_min quantite_max prix
----------- ----------- ------------ ----------
1           1           1            10.00
1           5           9            8.00
1           10          14           6.00
1           15          19           4.00
__________________
Stéphane
http://photos.nazgul.fr
Shiva est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/04/2011, 14h29   #10
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 953
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 953
Points : 17 773
Points : 17 773
MySQL n'est pas un SGBD Relationnel. C'est un ersatz. En fait un gestionnaire de fichiers avec une surcouche de SQL qui donne des résultats fantaisistes... En effet MySQL ne sait pas gérer les NULL, d'où des résultats de requête faux !

Utilisez un vrai SGBDR et abandonnez MySQL si vous voulez vraiment faire du SGBD relationnel !

A lire sur le sujet : http://blog.developpez.com/sqlpro/p9...udre-aux-yeux/

A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/04/2011, 11h56   #11
Membre du Club
 
Homme Stéphane
Développeur Web
Inscription : septembre 2005
Messages : 100
Détails du profil
Informations personnelles :
Nom : Homme Stéphane
Âge : 37
Localisation : France, Ille et Vilaine (Bretagne)

Informations professionnelles :
Activité : Développeur Web
Secteur : Services à domicile

Informations forums :
Inscription : septembre 2005
Messages : 100
Points : 45
Points : 45
Envoyer un message via MSN à Shiva
Oui ok c'est bien tout ça mais je n'ai pas la possibilité de changer donc je fais avec ce que j'ai.
__________________
Stéphane
http://photos.nazgul.fr
Shiva est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/04/2011, 11h43   #12
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 442
Points : 10 442
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Citation:
Envoyé par Shiva Voir le message
C'est justement ce que j'ai tenté au début mais le résultat était prévisible, c'est la première lignes de tarifs qui est retournée => "10.00"
Vous avez du faire une erreur en essayant, car avec des données (j'ai construit le test sur SQL-Server) :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
WITH panier (id_produit, quantite) AS
(
SELECT 1, 6
)
  ,  tarifs (id_produit, prix, quantite) AS
(
SELECT 1, 10,  1 union ALL
SELECT 1,  8,  5 union ALL
SELECT 1,  6, 10 union ALL
SELECT 1,  4, 15
)
 SELECT p.id_produit, p.quantite, COALESCE(MIN(t.prix), 0) AS prix
    FROM panier AS p
         LEFT OUTER JOIN tarifs AS t
           ON t.id_produit = p.id_produit
          AND t.quantite  <= p.quantite
GROUP BY p.id_produit, p.quantite
 
id_produit  quantite    prix
----------- ----------- -----------
1           6           8
N'oubliez pas que cette requête ne fonctionne que si le prix est toujours dégressif avec l'augmentation de quantité.
Si ce n'est pas un fait établi (voire contrôlé), il vaut mieux utiliser la vue proposée par SQLPro.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 06h06.


 
 
 
 
Partenaires

Hébergement Web