IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Trouver des valeurs non uniques dans une table


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Ingénieur Télécom
    Inscrit en
    Septembre 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur Télécom
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2011
    Messages : 11
    Points : 14
    Points
    14
    Par défaut Trouver des valeurs non uniques dans une table
    Bonjour,
    Débutant en SQL je tourne en rond depuis deux jours pour trouver la solution au problème suivant:
    Je gère une bdd de suivi de retours SAV.
    La table principale est donc remplie avec les retours des produits en SAV.

    Les champs de la table principale sont, entres autres:
    NumSerie et DateArrivée.
    Extrait:
    "A12083401578615307";"2011-05-16"
    "A12083401790515300";"2011-05-17"
    "A12083402650215309";"2011-05-16"
    "A12083401790515300";"2011-05-21"
    "A12083403027815306";"2011-05-16"

    Là où je coince c'est pour concevoir la requête qui me permettra de connaitre les produits qui sont revenus plusieurs fois en SAV.
    Ce sont donc les n° de série qui ne sont pas unique.
    ex:
    "A12083401790515300";"2011-05-17"
    "A12083401790515300";"2011-05-21"


    Par avance, merci pour votre aide

  2. #2
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Il faut filtrer avec having count(*) > 1

    Tu devras faire une sous-requête pour récupérer ensuite le max (ou min) de la date pour chaque numéro de série retourné par la sous-requête.
    On ne jouit bien que de ce qu’on partage.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Ingénieur Télécom
    Inscrit en
    Septembre 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur Télécom
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2011
    Messages : 11
    Points : 14
    Points
    14
    Par défaut
    Merci pour ta réponse.
    J'ai appliqué ton conseil. Hélas, je n'obtiens pas exactement ce que je cherche.

    Ci-dessous quelques données. En bleu, les données que je souhaite retrouver.
    Numero Serie Date Arrivee
    IE1000390502230168 2010-04-05
    IE1000390732230167 2010-04-14
    IE1000390807830162 2010-04-05
    IE1000390502230168 2011-04-05
    IE1000390732230167 2011-04-14
    IE1000390807830162 2011-04-05
    IE1000390973130165 2011-05-26
    IE1000390994630163 2011-05-24
    IE1000391056130164 2011-05-24
    IE1000391061130166 2011-06-01
    IE1000410073030162 2011-05-31

    La requête créée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT `Numero Serie`, `Date Arrivee` FROM `main`
    GROUP BY `Numero Serie` HAVING COUNT(`Numero Serie`) > 1
    et son résultat. Les n° de série concernés s'y trouvent mais seulement une fois.
    Numero Serie Date Arrivee
    IE1000390502230168 2010-04-05
    IE1000390732230167 2010-04-14
    IE1000390807830162 2010-04-05

    alors que je souhaite avoir ceci
    Numero Serie Date Arrivee
    IE1000390502230168 2010-04-05
    IE1000390732230167 2010-04-14
    IE1000390807830162 2010-04-05
    IE1000390502230168 2011-04-05
    IE1000390732230167 2011-04-14
    IE1000390807830162 2011-04-05

  4. #4
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Je suis très étonné que ta requête fonctionne : normalement, tous les champs qui ne font pas partie d'une fonction de regroupement doivent être dans le "group by" (donc numéro de série et date).

    Sinon, comme je te disais, il faut passer par une sous-requête.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT `Numero Serie`, `Date Arrivee` 
    FROM `main`
    where `Numero Serie` in 
    (
       select `Numero Serie`
       from `main`
       GROUP BY `Numero Serie` 
       HAVING COUNT(`Numero Serie`) > 1
    )
    On ne jouit bien que de ce qu’on partage.

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 763
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 763
    Points : 52 554
    Points
    52 554
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Je suis très étonné que ta requête fonctionne : normalement, tous les champs qui ne font pas partie d'une fonction de regroupement doivent être dans le "group by" (donc numéro de série et date)
    Cela fait partie des grosses M... de MySQL !

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

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  6. #6
    Membre à l'essai
    Homme Profil pro
    Ingénieur Télécom
    Inscrit en
    Septembre 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur Télécom
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2011
    Messages : 11
    Points : 14
    Points
    14
    Par défaut
    Super!!!
    C'est fou ce que j'apprends aujourd'hui!!
    Ça fonctionne parfaitement ainsi.

    Il ne reste qu'à améliorer les temps de réponse puisque ma base main contient pour l'instant 200 000 entrées et qu'elle va grossir très rapidement.
    Actuellement sur un serveur de test avec mySQL, cette requête dure au moins 1/2h.

    Aurais-tu quelques pistes?

  7. #7
    Membre à l'essai
    Homme Profil pro
    Ingénieur Télécom
    Inscrit en
    Septembre 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur Télécom
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2011
    Messages : 11
    Points : 14
    Points
    14
    Par défaut
    je me réponds à moi même.
    Je viens de lire le lien indiquer par sqlPro.
    Je comprends que mySQL n'est pas forcément l'outil le plus adapté à mon besoin ne serait-ce qu'en terme de performance.

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Bonjour,
    Tu peux essayer de remplacer le IN par une jointure:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT m1.`Numero Serie`, m2.`Date Arrivee` 
    FROM `main` as M1
    INNER JOIN `main`as m2 on m1.`Numero Serie` = m2.`Numero Serie` and m1.`Date Arrivee` <> m2.`Date Arrivee`

    Tatayo.

  9. #9
    Membre à l'essai
    Homme Profil pro
    Ingénieur Télécom
    Inscrit en
    Septembre 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur Télécom
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2011
    Messages : 11
    Points : 14
    Points
    14
    Par défaut
    Citation Envoyé par tatayo Voir le message
    Bonjour,
    Tu peux essayer de remplacer le IN par une jointure:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT m1.`Numero Serie`, m2.`Date Arrivee` 
    FROM `main` as M1
    INNER JOIN `main`as m2 on m1.`Numero Serie` = m2.`Numero Serie` and m1.`Date Arrivee` <> m2.`Date Arrivee`

    Tatayo.
    alors là, chapeau!!!
    Cette requête a duré moins de 5s.
    Je vais maintenant la décortiquer pour essayer de comprendre. Ça risque de me prendre du temps.

  10. #10
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 016
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 016
    Points : 23 705
    Points
    23 705
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Cela fait partie des grosses M... de MySQL !

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

    A +
    Autre lecture sur le sujet : http://cedric-duprez.developpez.com/...fier-group-by/
    Rédacteur / Modérateur SGBD et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  11. #11
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 763
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 763
    Points : 52 554
    Points
    52 554
    Billets dans le blog
    5
    Par défaut
    Oui, jai lu cela avec attention. Il se trouve que je dispose des CD de la norme IOS SQL dans toutes ses versions depuis la 1999.

    Or le papier est incomplet et la position de MySQL parfaitement irrespectueuse de la norme.

    Effectivement la norme SQL permet depuis la v 1999 un GROUP BY sur clef (PRIMAIRE ou UNIQUE) permettant d’omettre d'autres colonnes.
    mais cela fait partie des fonctionnalités avancées de la norme, c'est à dire que cette particularité ne doit être implémentée que dans le cadre ou le respect de la norme se fait en FULL LEVEL ! (Il y a 3 niveaux de conformité : ENTRY, INTERMEDIATE, FULL)

    Or en matière de respect de la norme SQL, MySQL en n'est même pas au niveau SQL 2 de 1992 (pas de schéma SQL par exemple) et donc bien entendu pas au niveau 1999 ni au niveau FULL.
    En comparaison, MS SQL Server se clame au niveau 2003, ENTRY...

    Bref encore une fois MySQL fait du n'importe quoi et s'arrange à la façon qui lui plait en non en conformité avec la norme.

    Aucun des grands éditeurs de SGBDR (Oracle, SQL Server, DB2 UDB, PostGreSQL...) n'a implémenté cette fonctionnalité qui n'a de sens que si tout le reste est déjà opérationnel !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  12. #12
    Membre expérimenté
    Avatar de islamov2000
    Homme Profil pro
    Ingénieur d'études & developpement en informatique
    Inscrit en
    Septembre 2007
    Messages
    814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur d'études & developpement en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2007
    Messages : 814
    Points : 1 717
    Points
    1 717
    Billets dans le blog
    6
    Par défaut
    Essayes aussi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT M1.`Numero Serie`, M1.`Date Arrivee`
    FROM `main` AS M1
    INNER JOIN
    (
       SELECT `Numero Serie`
       FROM `main`
       GROUP BY `Numero Serie`
       HAVING COUNT(`Numero Serie`) > 1
    )as M2 ON M1.`Numero Serie`=M2.`Numero Serie`
    d'avoir Pensé à voter positivement pour ceux qui vous ont aidés et surtout à mettre si le cas.
    ça encourage.

Discussions similaires

  1. Réponses: 2
    Dernier message: 02/04/2012, 08h34
  2. Réponses: 2
    Dernier message: 27/07/2011, 12h16
  3. Réponses: 2
    Dernier message: 11/05/2009, 09h36
  4. Récupérer des lignes non enregistrées dans une table
    Par leddy dans le forum Langage SQL
    Réponses: 2
    Dernier message: 24/04/2008, 15h09
  5. nombre de valeurs non nulles dans une tables
    Par 080983 dans le forum SQL
    Réponses: 33
    Dernier message: 27/08/2007, 12h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo