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 19/01/2011, 10h18   #1
Invité de passage
 
Inscription : janvier 2011
Messages : 21
Détails du profil
Informations forums :
Inscription : janvier 2011
Messages : 21
Points : 2
Points : 2
Par défaut IN et GROUP BY impossible ?

Bonjour,

J'ai un souci niveau requete SQL.

J'ai une table mvt avec les colonnes :
- mvt_num : action incrémenté (clé primaire)
- mvt_act_num : numero de l'action
- mvt_plc : place de l'action
- mvt_dte = date de l'action

Requête:
Code :
1
2
3
4
5
6
SELECT mvt_act_num
FROM mvt
WHERE mvt_plc=1
AND mvt_act_num IN (SELECT mvt_act_num, Max(mvt_dte) 
FROM mvt
GROUP BY mvt_act_num)
Il peut y avoir plusieurs fois la même action (mvt_act_num)
Je souhaite obtenir la liste des numéros d'action sur la place 1 uniquement.

Je récupère donc la dernière date de l'action avec la sous requête *
Je récupère uniquement ceux en place = 1 *


Cependant j'ai trop de valeur dans la sous requête.
Ça me jette car on ne peut pas faire un IN sur plusieurs colonnes.

Quelqu'un aurait il une solution s'il vous plait ?

Merci d'avance
cbprogs est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 10h35   #2
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Bonjour,

Votre requête ne peut pas fonctionner, car la sous requête renvoie deux colonnes, alors que IN suppose une seule colonne.
Enfin je ne suis pas sûr de bien comprendre votre besoin

Citation:
Envoyé par cbprogs Voir le message
Bonjour,
Je souhaite obtenir la liste des numero d'action sur la place 1 uniquement.
Alors vous n'aviez pas besoin de votre deuxième filtre...
Citation:
Je recupère donc la dernière date de l'action avec la sous requete
Est-ce que vous ne voulez les résultats que pour la dernière action en date ?

Est-ce que cette requête répond à votre besoin : ?
Code :
1
2
3
SELECT mvt_act_num
FROM mvt
WHERE mvt_plc=1 AND mvt_dte = (SELECT Max(mvt_dte) FROM mvt)
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 10h44   #3
Invité de passage
 
Inscription : janvier 2011
Messages : 21
Détails du profil
Informations forums :
Inscription : janvier 2011
Messages : 21
Points : 2
Points : 2
Merci mais la requete que vous me proposez ne va pas.

En fait le contenu de ma table est de ce genre :

mvt_num | mvt_act_num | mvt_plc | mvt_dte
.....0.................0................0........19/01/2011 - 10:10:00
.....1.................0................1........19/01/2011 - 10:00:00
.....2.................1................2........19/01/2011 - 10:15:00
.....3.................2................0........19/01/2011 - 10:00:00
.....4.................2................1........19/01/2011 - 10:08:00
.....5.................2................2........19/01/2011 - 10:10:00

Donc si je souhaite avoir uniquement les mvt_act_num qui sont en 1 votre requete fonctionne mais je souhaite avoir les mvt_act_num qui ont la derniere date dont la plc =1

Donc le resultat doit être :
mvt_act_num= 1 uniquement

Le 2 est en plc=2 dans sa dernière date.

J'espère que mon explication est claire

Merci
cbprogs est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 10h52   #4
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
hmmm

ceci ?
Code sql :
1
2
3
4
5
6
7
8
9
 
SELECT mvt_act_num
FROM mvt
WHERE mvt_plc=1
AND mvt_dte = (
  SELECT Max(mvt_dte) 
  FROM mvt
  WHERE mvt_plc = 1
)
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 10h55   #5
Invité de passage
 
Inscription : janvier 2011
Messages : 21
Détails du profil
Informations forums :
Inscription : janvier 2011
Messages : 21
Points : 2
Points : 2
Le problème de

Code :
1
2
3
SELECT Max(mvt_dte) 
FROM rim_mvt
WHERE mvt_plc = 1
est que je n'ai que la dernière date et non la dernière date de chaque mvt_act_num.

C'est pourquoi j'avais mis un group by par mvt_act_num
J'avais la liste avec la dernière action

Je ne sais pas du tout comment résoudre ce souci
cbprogs est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 11h09   #6
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 986
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 10 986
Points : 18 234
Points : 18 234
Envoyer un message via MSN à CinePhil
Citation:
Envoyé par cbprogs Voir le message
En fait le contenu de ma table est de ce genre :

mvt_num | mvt_act_num | mvt_plc | mvt_dte
.....0.................0................0........19/01/2011 - 10:10:00
.....1.................0................1........19/01/2011 - 10:00:00
.....2.................1................2........19/01/2011 - 10:15:00
.....3.................2................0........19/01/2011 - 10:00:00
.....4.................2................1........19/01/2011 - 10:08:00
.....5.................2................2........19/01/2011 - 10:10:00

Donc si je souhaite avoir uniquement les mvt_act_num qui sont en 1 votre requete fonctionne mais je souhaite avoir les mvt_act_num qui ont la derniere date dont la plc =1

Donc le resultat doit être :
mvt_act_num= 1 uniquement

Le 2 est en plc=2 dans sa dernière date.

J'espère que mon explication est claire
Non c'est pas clair !

Citation:
je souhaite avoir les mvt_act_num qui ont la derniere date dont la plc =1
Tu veux uniquement les mvt_act_num qui ont plc=1 pour leur dernière date ?

Ça ne colle pas avec le résultat attendu :
Citation:
Donc le resultat doit être :
mvt_act_num= 1 uniquement
Alors que dans tes données, mvt_act_num = 1 a plc = 2 pour son unique date :
Citation:
mvt_num | mvt_act_num | mvt_plc | mvt_dte
.....0.................0................0........19/01/2011 - 10:10:00
.....1.................0................1........19/01/2011 - 10:00:00
.....2.................1................2........19/01/2011 - 10:15:00
.....3.................2................0........19/01/2011 - 10:00:00
.....4.................2................1........19/01/2011 - 10:08:00
.....5.................2................2........19/01/2011 - 10:10:00
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 11h15   #7
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
je crois que je commence a comprendre...

quel est votre SGBDR ?

essayez ceci :
Code sql :
1
2
3
4
5
6
7
8
9
10
11
 
SELECT mvt_act_num
FROM mvt
INNER JOIN (
  SELECT mvt_act_num, Max(mvt_dte) AS MaxDte
  FROM mvt
  GROUP BY mvt_act_num
) AS tmp 
  ON mvt.mvt_act_num = tmp.mvt_act_num
  AND mvt.mvt_dte = tmp.MaxDte
WHERE mvt_plc=1
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 11h18   #8
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Citation:
Envoyé par CinePhil Voir le message
Ça ne colle pas avec le résultat attendu :
Oui, j'ai supposé que c'était une erreur dans son jeu d'essai...

j'essaie de comprendre aussi

@cbprogs :
peux-tu nous dire ce que représentent ces données, et ce que tu veux obtenir ?
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 11h21   #9
Invité de passage
 
Inscription : janvier 2011
Messages : 21
Détails du profil
Informations forums :
Inscription : janvier 2011
Messages : 21
Points : 2
Points : 2
Je suis sous Oracle 10g

ca me met : Mot cle absent pour AS tmp

Exact pour le jeu d'essai désolé
Prenez plutot celui la :

mvt_num | mvt_act_num | mvt_plc | mvt_dte
.....0.................0................0........19/01/2011 - 10:10:00
.....1.................0................1........19/01/2011 - 10:00:00
.....2.................1................2........19/01/2011 - 10:15:00
.....3.................2................0........19/01/2011 - 10:00:00
.....4.................2................2........19/01/2011 - 10:08:00
.....5.................2................1........19/01/2011 - 10:10:00

Le resultat doit être 2


mvt_num = clé primaire auto incréménté
mvt_act_num est un numéro d'action (table d'action) donc clé etrangère
mvt_plc est sa place
mvt_date, sa date de placement

Je souhaite avoir toutes les actions qui sont en place 1
Quand je parle de date c'est que la place qui doit être prise en compte pour chacune des action doit être la plus récente.
cbprogs est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 11h29   #10
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Citation:
Envoyé par cbprogs Voir le message
Je suis sous Oracle 10g

ca me met : Mot cle absent pour AS tmp

Enlevez simplement le AS
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 19/01/2011, 11h32   #11
Invité de passage
 
Inscription : janvier 2011
Messages : 21
Détails du profil
Informations forums :
Inscription : janvier 2011
Messages : 21
Points : 2
Points : 2
C'est exactement cela

Merci beaucoup
Par contre, puis je avoir une petite explication s'il vous plait ?
cbprogs est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 11h34   #12
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 986
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 10 986
Points : 18 234
Points : 18 234
Envoyer un message via MSN à CinePhil
Quelle est la dernière date de chaque action ?
Code :
1
2
3
SELECT mvt_act_num, MAX(mvt_date) AS derniere_date
FROM mvt
GROUP BY mvt_act_num
Quelle est la place de cette dernière date ?
Code :
1
2
3
4
5
6
7
8
9
10
SELECT m.mvt_act_num, m.mvt_plc, m.mvt_date
FROM mvt m
INNER JOIN
(
    SELECT mvt_act_num, MAX(mvt_date) AS derniere_date
    FROM mvt
    GROUP BY mvt_act_num
) tmp 
    ON tmp.mvt_act_num = m.mvt_act_num
    AND tmp.derniere_date = m.mvt_date
On ne retient que les plc = 1 :
Code :
1
2
3
4
5
6
7
8
9
10
11
SELECT m.mvt_act_num, m.mvt_plc, m.mvt_date
FROM mvt m
INNER JOIN
(
    SELECT mvt_act_num, MAX(mvt_date) AS derniere_date
    FROM mvt
    GROUP BY mvt_act_num
) tmp 
    ON tmp.mvt_act_num = m.mvt_act_num
    AND tmp.derniere_date = m.mvt_date
WHERE m.mvt_plc = 1
Je n'avais pas regardé la requête de aieeeuuuuu mais j'arrive à la même.

En plus de la phrase en bleu de ma signature, tu devrais aussi lire "Le discours de la méthode" qui préconise notamment de décomposer un problème complexe en problèmes plus simples. C'est la meilleure méthode pour construire des requêtes SQL complexes.
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 19/01/2011, 11h37   #13
Invité de passage
 
Inscription : janvier 2011
Messages : 21
Détails du profil
Informations forums :
Inscription : janvier 2011
Messages : 21
Points : 2
Points : 2
Merci a vous deux.

Exxxxcellent !
cbprogs est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h13.


 
 
 
 
Partenaires

Hébergement Web