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

Requêtes MySQL Discussion :

Requête SELECT retourne NULL


Sujet :

Requêtes MySQL

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 414
    Points : 187
    Points
    187
    Par défaut Requête SELECT retourne NULL
    Bonsoir à tous,
    ce soir je sèche sur un problème que je pensais être simple…
    J'ai 2 tables distinctes, table1 (étudiant) table2 (enseignant). Lors de l'identification initiale le visiteur entre et valide son e-mail. À ce stade il n'est identifié ni comme enseignant ni comme étudiant ce qui semble normal, lorsqu'il valide son entrée je souhaite lancer une requête qui va vérifier dans les deux tables où se trouve le bon e-mail ce qui déclenche des scripts utilisant la table1 ou la table2 selon le E-Mail. J'ai commencé à écrire une requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT table1.*, table2.* FROM table1
    LEFT JOIN table2 AS enseignant ON enseignant.email = 'sffdsqfqfdqgmail.com';
    WHERE table1.email =  'sffdsqfqfdqgmail.com'
    J'ai identifié le pb : lorsque le login est un login d'enseignant le SELECT table1 retourne NULL et ça coince pour la suite !
    J'ai tenté diverses function IF NULL, IF NOTNULL, COALESCE etc, rien n'a fonctionné ! En fait je patauge grave !
    Si qqu'un peut me mettre sur une piste d'avance merci

    [MàJ] Je viens de tenter ceci mais ça ne fonctionne pas, erreur de syntaxe ! où ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT * COALESCE(NULL, 'A'), table2.*
    		FROM table1
    		LEFT JOIN table2 ON Email = 'khkjhkhkhkhkkjhkhihh@gmail.com'
    		WHERE table1.Email =  'khkjhkhkhkhkkjhkhihh@gmail.com'

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 133
    Points : 38 556
    Points
    38 556
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    Vous pouvez faire comme ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT DISTINCT COALESCE(T1.QUOI, T2.QUOI, T0.QUOI)               
    FROM (SELECT 'monadressemail' AS CDMAIL, 'RIEN' AS QUOI) as T0    
    LEFT OUTER JOIN                                                   
         (SELECT 'monadressemail' AS CDMAIL, 'ETUD' AS QUOI                               
          FROM T_Etudiant) AS T1                                       
      ON T1.CDMAIL=T0.CDMAIL
    LEFT OUTER JOIN                                                   
         (SELECT 'monadressemail' AS CDMAIL, 'PROF' AS QUOI                               
          FROM T_enseignant) AS T2                                       
      ON T2.CDMAIL=T0.CDMAIL

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 414
    Points : 187
    Points
    187
    Par défaut
    Merci pour ta réponse, je regarde ceci dans la journée
    Cdlt

  4. #4
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 379
    Points : 19 060
    Points
    19 060
    Par défaut
    Salut bronon.

    Citation Envoyé par bronon
    je souhaite lancer une requête qui va vérifier dans les deux tables où se trouve le bon e-mail
    Autrement dit, tu désires savoir si le email est présent dans la table des étudiants ou dans la table des enseignants.

    Citation Envoyé par bronon
    lorsque le login est un login d'enseignant le SELECT table1 retourne NULL
    C'est tout à fait normal. Donc tu n'utilises pas la bonne approche pour extraire l'information dont tu as beson.

    Citation Envoyé par bronon
    J'ai tenté diverses function IF NULL, IF NOTNULL, COALESCE etc, rien n'a fonctionné !
    Tu te complique l'existence.

    Pour ce faire, tu utilises un union sur tes deux tables.
    Dans le premier select, tu recherches si l'email est présent dans la table des étudiants.
    Dans le seconde select, tu recherches si l'email est présent dans la table des enseignants.

    Ce qui fait au total quatre cas à gérer par la suite :
    1) aucune ligne n'est retourné --> pas d'identification possible.
    2) une ligne mais en provenance de la table des enseignants --> c'est un prof
    3) une ligne mais en provenance de la table des étudiants --> c'est un élève.
    4) deux lignes sont retournées --> problème car il est à la fois prof et élève !

    Pour te faciliter la compréhension, dans mon exemple, je t'ai traité les quatre cas avec la même requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE `base`
            DEFAULT CHARACTER SET `latin1`
            DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `etudiant`
    --------------
     
    --------------
    CREATE TABLE `etudiant`
    (
      `id`     integer unsigned NOT NULL AUTO_INCREMENT primary key,
      `email`  varchar(255)     NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    INSERT INTO `etudiant` (`email`) VALUES
    ('alpha@site.com'),
    ('beta@site.com'),
    ('gamma@site.com'),
    ('delta@site.com'),
    ('omicron@site.com')
    --------------
     
    --------------
    select * from etudiant
    --------------
     
    +----+------------------+
    | id | email            |
    +----+------------------+
    |  1 | alpha@site.com   |
    |  2 | beta@site.com    |
    |  3 | gamma@site.com   |
    |  4 | delta@site.com   |
    |  5 | omicron@site.com |
    +----+------------------+
    --------------
    DROP TABLE IF EXISTS `enseignant`
    --------------
     
    --------------
    CREATE TABLE `enseignant`
    (
      `id`     integer unsigned NOT NULL AUTO_INCREMENT primary key,
      `email`  varchar(255)     NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    INSERT INTO `enseignant` (`email`) VALUES
    ('omicron@site.com'),
    ('phi@site.com'),
    ('khi@site.com'),
    ('psi@site.com'),
    ('omega@site.com')
    --------------
     
    --------------
    select * from enseignant
    --------------
     
    +----+------------------+
    | id | email            |
    +----+------------------+
    |  1 | omicron@site.com |
    |  2 | phi@site.com     |
    |  3 | khi@site.com     |
    |  4 | psi@site.com     |
    |  5 | omega@site.com   |
    +----+------------------+
    --------------
    select 'eleve' as type, id, email
    from etudiant
    where email = 'iota@site.com'
    union
    select 'prof' as type, id, email
    from enseignant
    where email = 'iota@site.com'
    --------------
     
    --------------
    select 'eleve' as type, id, email
    from etudiant
    where email = 'delta@site.com'
    union
    select 'prof' as type, id, email
    from enseignant
    where email = 'delta@site.com'
    --------------
     
    +-------+----+----------------+
    | type  | id | email          |
    +-------+----+----------------+
    | eleve |  4 | delta@site.com |
    +-------+----+----------------+
    --------------
    select 'eleve' as type, id, email
    from etudiant
    where email = 'phi@site.com'
    union
    select 'prof' as type, id, email
    from enseignant
    where email = 'phi@site.com'
    --------------
     
    +------+----+--------------+
    | type | id | email        |
    +------+----+--------------+
    | prof |  2 | phi@site.com |
    +------+----+--------------+
    --------------
    select 'eleve' as type, id, email
    from etudiant
    where email = 'omicron@site.com'
    union
    select 'prof' as type, id, email
    from enseignant
    where email = 'omicron@site.com'
    --------------
     
    +-------+----+------------------+
    | type  | id | email            |
    +-------+----+------------------+
    | eleve |  5 | omicron@site.com |
    | prof  |  1 | omicron@site.com |
    +-------+----+------------------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
     
    Appuyez sur une touche pour continuer...
    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 414
    Points : 187
    Points
    187
    Par défaut
    Merci pour ta réponse mais le pb est que les 2 table n'ont pas la même dimension ce qui exclu UNION et de mon expérience les clients ont toujours besoin de rajouter des "trucs" ce qui obligerait à modifier 2 tables en même temps.

    Cdlt

  6. #6
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 379
    Points : 19 060
    Points
    19 060
    Par défaut
    Salut bronon.

    Citation Envoyé par Bronon
    le pb est que les 2 table n'ont pas la même dimension ce qui exclu UNION
    Je ne voie pas pourquoi.
    Ta question était de savoir si l'on pouvait identifier un email dans tes deux tables. Je t'ai donné un exemple qui donne une réponse.
    A toi ensuite de l'adapté à ce que tu veux faire, entre autre accepter ou refuser la connexion à un compte (login), puisque c'est cela le problème.

    Citation Envoyé par Bronon
    et de mon expérience les clients ont toujours besoin de rajouter des "trucs" ce qui obligerait à modifier 2 tables en même temps.
    Mais pourquoi veux-tu ajouter d'autres colonnes à ce union ?
    Ce test a pour but de valider ou de rejeter une connexion, en identifiant l'email dans tes deux tables.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  7. #7
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 133
    Points : 38 556
    Points
    38 556
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par bronon Voir le message
    Merci pour ta réponse, je regarde ceci dans la journée
    Cdlt
    Finalement cette solution vous convient elle ?

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 414
    Points : 187
    Points
    187
    Par défaut
    Je reviens vers vous après avoir été contraint par des impératifs autre que ce développement.

    Après réflexion j'ai mieux analysé mon besoin :

    Je veux rechercher un E-Mail dans 2 table différentes et pas de même taille, j'ai donc écrit la requête suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT etudiant.*, enseignant.*  
    	FROM etudiant
    	LEFT JOIN enseignant ON enseignant.Email = 'hfhgfhgg@gmail.com'
    	WHERE etudiant.Email =  'hfhgfhgg@gmail.com'
    Le code fonctionne sans pb et retourne bien les valeurs recherchées quand le Email se trouve dans la table « etudiant » mais ne retourne rien si le Email se trouve dans la table « enseignant » !!!!
    J'ai également essayé avec une directive COALESCE(NULL, 'A') dans la clause SELECT ==> Wallou;
    Si qqu'un peut m'éclairer ou m'indiquer une piste, d'avance merci.

  9. #9
    Membre confirmé Avatar de Sebwar
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2012
    Messages
    172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2012
    Messages : 172
    Points : 498
    Points
    498
    Par défaut
    Hello !

    Pourquoi ne pas faire deux requêtes ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT email FROM etudiant WHERE email = 'email@domain.tld'
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT email FROM enseignant WHERE email = 'email@domain.tld'
    ou en "une" requête retournant deux colonnes (email, categorie) : email@domain.tld, étudiant ET/OU email@domain.tld, enseignant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT email, 'étudiant' AS categorie FROM etudiant WHERE email = 'email@domain.tld'
    UNION
    SELECT email,  'enseignant' AS categorie FROM enseignant WHERE email = 'email@domain.tld'

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 414
    Points : 187
    Points
    187
    Par défaut
    Ah qu'elle est bonne ta solution qui fonctionne parfaitement ! Merci
    Par contre ta solution monopolise le serveur pendant 0,014 seconde tandis que la mienne avec LEFT JOIN (qui ne retourne rien j'en conviens) ne monopolise le serveur que pendant 0,001 seconde (14 fois moins longtemps) ! En cas de gros traffic ça peut devenir pénalisant !

    Ta solution de 2 SELECT coup sur coup, C ce que j'utilise en ce moment mais temps serveur 0,012 seconde !! D'où mon retour sur le forum.

    Néanmoins encore merci

    Pourquoi cette foutue jointure ne fonctionne-t-elle pas ! Grrrrrrr

  11. #11
    Membre confirmé Avatar de Sebwar
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2012
    Messages
    172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2012
    Messages : 172
    Points : 498
    Points
    498
    Par défaut
    0,014 seconde ce n'est pas énorme

    Vérifie que tu as bien un index sur le champs "email"
    Sinon une autre solution serait de faire de l'héritage : une table parent "personne" et 2 tables fille "étudiant" et "enseignant", la table "personne" contenant les champs communs de tes tables actuelles "etudiant" et "enseignant" ducoup pour se connecter tu n'aurais qu'a taper dans la table "personne"

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 414
    Points : 187
    Points
    187
    Par défaut
    Citation Envoyé par Sebwar Voir le message
    0,014 seconde ce n'est pas énorme

    Vérifie que tu as bien un index sur le champs "email"
    "
    Merci pour ta réponse,
    J'ai bien des index sur Email de chaque table.

    Concernant les temps de réponse sache que 0,014 s est énorme, aujourd'hui les temps de réponse d'un serveur à une requête de ce type C plutôt le millième de seconde, les serveur les + performants réalisent ce genre d'opération en nano voir pico seconde ! (10 puis -9, 10 puis -12)
    Et ma jointure ? une idée ?
    Cdlt

  13. #13
    Membre confirmé Avatar de Sebwar
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2012
    Messages
    172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2012
    Messages : 172
    Points : 498
    Points
    498
    Par défaut
    Ta requête LEFT JOIN est fausse : tu prends la table étudiant filtré sur l'email (where Email = 'hfhgfhgg@gmail.com') et tu lui greffe (LEFT JOIN) la table enseignant filtré sur l'email (ON enseignant.Email = 'hfhgfhgg@gmail.com') donc si l'email recherché est un email de la table enseignant, tu n'auras aucun résultat car ta requête va essayer de joindre [la table enseignant filtré sur l'email] sur [rien] (rien = table étudiant filtré sur un email qui n'est pas dans la table etudiant)
    Donc comparer le temps d’exécution d'une requête fausse avec une requête qui retourne le bon résultat n'a aucun sens !

    Au niveau du temps d’exécution, je ne comprend pas quel est le soucis avec 0.014s
    Mais si ça te gène vraiment, il y a des serveurs qui vont plus vite comme tu le dis ! donc tu peux changer de serveur même si a mon avis c'est inutile

  14. #14
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 414
    Points : 187
    Points
    187
    Par défaut
    Le problème de la vitesse d'exécution n'est qu'un aparté d'autant que je suis en phase de développement et non en prod.
    Enfin en prod je ne serai plus maître de l'hébergement donc quid de ce problème. Juste pour info le mécanisme de base d'une recherche est un balayage des données jusqu'au point d'équivalence entre la valeur lue et la demande, si il ne trouve rien le « curseur » balaie l'intégralité de la table tandis dès qu'il trouve l'équivalence il abroge le processus …

    Le vrai pb est comment faire pour résoudre mon pb.

  15. #15
    Membre confirmé Avatar de Sebwar
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2012
    Messages
    172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2012
    Messages : 172
    Points : 498
    Points
    498
    Par défaut
    Citation Envoyé par bronon
    Juste pour info le mécanisme de base d'une recherche est un balayage des données jusqu'au point d'équivalence entre la valeur lue et la demande, si il ne trouve rien le « curseur » balaie l'intégralité de la table tandis dès qu'il trouve l'équivalence il abroge le processus …
    Dans notre cas c'est faux ! il y a un index sur le champ email donc ça ne va pas scanner la table, ça va aller taper dans l'index. Celui-ci étant en B-TREE ça ne va pas scanner l'intégralité des valeurs.

    Citation Envoyé par bronon
    Le vrai pb est comment faire pour résoudre mon pb.
    Vu que la requête avec UNION résout le problème, que faut il de plus ?

  16. #16
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 379
    Points : 19 060
    Points
    19 060
    Par défaut
    Salut Bronon.

    Citation Envoyé par bronon
    Si qqu'un peut m'éclairer ou m'indiquer une piste, d'avance merci.
    Je vous ai donné la solution, mais vous l'avez rejeté. J'ai même pris le temps de vous faire un script avec un jeu d'essai pour vous donner un exemple.

    Citation Envoyé par bronon
    Ah qu'elle est bonne ta solution qui fonctionne parfaitement ! Merci
    La solution donnée par Sebwar est identique à ma solution et c'est lui que vous remerciez.

    Citation Envoyé par bronon
    Pourquoi cette foutue jointure ne fonctionne-t-elle pas !
    Parce que cela ne répond pas à votre besoin.

    Si l'email est présent dans la première table alors cela retourne la ligne.
    Si l'émail est présent dans la seconde table, donc de surcroit, elle n'est pas présente dans la première table, cela ne vous retourne rien.
    La solution est de faire un union entre les deux extractions, ce qui correspond soit à la présente dans la première table ou soit à la présente dans la seconde table.

    Citation Envoyé par bronon
    J'ai bien des index sur Email de chaque table.
    En admettant que vos email soient uniques dans une table donnée, il suffit de faire un "unique index" pour résoudre le problème.

    Maintenant pourquoi cela prend plus de temps ?
    Un UNION n'a pas la réputation d'être très performant car vous devez lire autant de fois qu'il y a de subdivisions dans votre unions (ici 2).
    J'ai repris mes exemples en essayant de trouver une solution performance, mais sans succès.
    Dans le tableau ci-après, les tests de performances sur mes quatres cas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    --------------
    SHOW PROFILES
    --------------
     
    +----------+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Query_ID | Duration   | Query                                                                                                                                                                                          |
    +----------+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    |        1 | 0.00069925 | (select 'eleve' as type, id, email from etudiant   where email = 'iota@site.com'    limit 1) union (select 'prof' as type, id, email from enseignant where email = 'iota@site.com' limit 1)    |
    |        2 | 0.00044800 | select  'eleve' as type, id, email from etudiant   where email = 'iota@site.com'    limit 1                                                                                                    |
    |        3 | 0.00044850 | select  'prof'  as type, id, email from enseignant where email = 'iota@site.com'    limit 1                                                                                                    |
    |        4 | 0.00132400 | (select 'eleve' as type, id, email from etudiant   where email = 'delta@site.com'   limit 1) union (select 'prof' as type, id, email from enseignant where email = 'delta@site.com' limit 1)   |
    |        5 | 0.00130725 | (select 'eleve' as type, id, email from etudiant   where email = 'phi@site.com'     limit 1) union (select 'prof' as type, id, email from enseignant where email = 'phi@site.com' limit 1)     |
    |        6 | 0.00133625 | (select 'eleve' as type, id, email from etudiant   where email = 'omicron@site.com' limit 1) union (select 'prof' as type, id, email from enseignant where email = 'omicron@site.com' limit 1) |
    |        7 | 0.00048400 | select  'eleve' as type, id, email from etudiant   where email = 'omicron@site.com' limit 1                                                                                                    |
    |        8 | 0.00047825 | select  'prof'  as type, id, email from enseignant where email = 'omicron@site.com' limit 1                                                                                                    |
    +----------+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    Exemple d'une requête ne produisant aucun résultats (1) et la même décomposée (2 & 3).
    --> l'union est plus court.

    Exemple d'une requête produisant deux résultats (6) et la même décomposée (7 & 8).
    --> L'union est plus long.

    Maintenant, il est difficile de faire mieux que le résultat produit ici.

    Une autre solution consiste juste à vérifier l'existence de l'email. Autrement dit, on change la structure de la requête.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    --------------
    explain
    select 1 from dual where exists (select 1 from etudiant where email = 'omicron@site.com') or exists (select 1 from enseignant where email = 'omicron@site.com')
    --------------
     
    +----+-------------+------------+------------+-------+---------------+------+---------+-------+------+----------+----------------+
    | id | select_type | table      | partitions | type  | possible_keys | key  | key_len | ref   | rows | filtered | Extra          |
    +----+-------------+------------+------------+-------+---------------+------+---------+-------+------+----------+----------------+
    |  1 | PRIMARY     | NULL       | NULL       | NULL  | NULL          | NULL | NULL    | NULL  | NULL |     NULL | No tables used |
    |  3 | SUBQUERY    | enseignant | NULL       | const | idx2          | idx2 | 255     | const |    1 |   100.00 | Using index    |
    |  2 | SUBQUERY    | etudiant   | NULL       | const | idx1          | idx1 | 255     | const |    1 |   100.00 | Using index    |
    +----+-------------+------------+------------+-------+---------------+------+---------+-------+------+----------+----------------+
    --------------
    RESET QUERY CACHE
    --------------
     
    --------------
    set profiling=1
    --------------
     
    --------------
    select 1 from dual where exists (select 1 from etudiant where email = 'omicron@site.com') or exists (select 1 from enseignant where email = 'omicron@site.com')
    --------------
     
    +---+
    | 1 |
    +---+
    | 1 |
    +---+
    --------------
    SHOW PROFILES
    --------------
     
    +----------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Query_ID | Duration   | Query                                                                                                                                                           |
    +----------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
    |        1 | 0.00057675 | select 1 from dual where exists (select 1 from etudiant where email = 'omicron@site.com') or exists (select 1 from enseignant where email = 'omicron@site.com') |
    +----------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
    C'est plus rapide, mais est-ce que cela répond à votre attente ?

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  17. #17
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 133
    Points : 38 556
    Points
    38 556
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    Bonjour,

    Vous pouvez faire comme ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT DISTINCT COALESCE(T1.QUOI, T2.QUOI, T0.QUOI)               
    FROM (SELECT 'monadressemail' AS CDMAIL, 'RIEN' AS QUOI) as T0    
    LEFT OUTER JOIN                                                   
         (SELECT 'monadressemail' AS CDMAIL, 'ETUD' AS QUOI                               
          FROM T_Etudiant) AS T1                                       
      ON T1.CDMAIL=T0.CDMAIL
    LEFT OUTER JOIN                                                   
         (SELECT 'monadressemail' AS CDMAIL, 'PROF' AS QUOI                               
          FROM T_enseignant) AS T2                                       
      ON T2.CDMAIL=T0.CDMAIL
    bonjour,

    Je vous avais proposé cette solution, normalement bien plus rapide qu'une union, et que j'avais testée avec succès, aviez vous testé de votre coté pour vérifier l'adéquation avec votre besoin ?

  18. #18
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 414
    Points : 187
    Points
    187
    Par défaut
    Merci pour ta réponse mais je ne comprends pas ta requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select 1 from dual where exists (select 1 from etudiant where email = 'omicron@site.com') or exists (select 1 from enseignant where email = 'omicron@site.com')
    Je n'ai pas l'habitude d'utiliser ces méthodes, ta requête mise in extenso dans la console SQL de PhP Admin fonctionne mais me retourne 1 ????
    Je souhaite récupérer qq col (id, Statut, Nom par ex col commune au 2 tables) avec ta requête je récupère 1 ???

    Mais je dois manquer un épisode !

    Cdlt

  19. #19
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 133
    Points : 38 556
    Points
    38 556
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    J'ai cru que c'était pour moi je vois que non, avez vous testé ?

  20. #20
    Membre confirmé Avatar de Sebwar
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2012
    Messages
    172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2012
    Messages : 172
    Points : 498
    Points
    498
    Par défaut
    Citation Envoyé par Artemus24
    La solution donnée par Sebwar est identique à ma solution et c'est lui que vous remerciez.
    Je suis un voleur de solution
    J'ai pris le sujet en cours de route, au post #8 le besoin avait l'air d'être reformulé du coup je n'ai pas lu les posts d'avant (pas bien !) mais sinon oui c'est bien la même solution !

    La solution de escartefigue fonctionne très bien, chez moi elle prend un peu plus de temps mais à ce niveau ce n'est pas significatif.
    La requête d'Artemus24 "FROM dual" aurait été une bonne solution si vous n'aviez pas a récupérer de colonnes supplémentaires.

    Ce qui prend du temps ça va être la recherche de l'email dans l'index et dans toutes les solutions proposés ça passe par un scan des index.

    Prenez la requête UNION ou prenez la requête LEFT JOIN, je ne comprend pas ce que vous cherchez de plus ?

Discussions similaires

  1. [EJB3UNIT] Exécution de requête SQL retourne null
    Par Lordsephiroth dans le forum JPA
    Réponses: 4
    Dernier message: 02/08/2011, 08h30
  2. Réponses: 3
    Dernier message: 28/04/2010, 08h12
  3. [MySQL] requête select qui ne retourne qu'une seule ligne
    Par rose25 dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 03/07/2009, 15h11
  4. Requête select into qui ne retourne rien
    Par madevilts dans le forum PL/SQL
    Réponses: 6
    Dernier message: 15/10/2008, 16h25
  5. opérateur + dans SELECT retourne null ?
    Par david_chardonnet dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 19/01/2007, 10h47

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