Partage
  • Partager sur Facebook
  • Partager sur Twitter

[MS SERVER] Effectuer des AND sur une même colonne

Sujet résolu
    11 octobre 2018 à 11:35:11

    Bonjour !

    Je suis actuellement en train de faire un petit exercice pour mon site, et voilà mon soucis :

    J'ai à ma disposition une table (simplifiée ici) recensant des personnes : une colonne ID en PK, une colonne nom et une colonne prénom. On considère qu'il n'y a pas d'homonymes : il peut y avoir plusieurs personnes ayant le même nom ou ayant le même prénom, mais jamais les deux à la fois.

    Exemple :

    ID - NOM - PRENOM

    1 - DUPONT - PIERRE

    2 - DURAND - ANTOINE

    3 - DUPONT - SYLVAIN

    4 - MAUGER - DAVID

    5 - MULLER - PIERRE

    Je cherche à retourner une liste de famille (=noms) qui contiennent une liste de personnes envoyée en paramètres (nombre de paramètres fixe, mais chaque paramètre est potentiellement NULL). Exemple 1, je cherche les familles qui ont pour membres Pierre et Sylvain : on revoit Dupont. Exemple 2, je cherche pour le membre Pierre (2e param de prénom NULL), on renvoie Dupont et Muller.

    L'idée d'origine que j'ai eu était de faire un WHERE prenom IN (param1, param2, ..., paramN) qui me renvoie la liste des famille ayant au moins un de ces prénoms comme membre. J'ai ensuite essayé de faire un GROUP BY par nom, en COUNTant les prénoms pour ensuite comparer ce COUNT au nombre de paramètres non nuls que j'avais précédemment calculé avant la requête, mais ça ne fonctionne pas. Ma demande revient au fait de faire des AND successifs sur une seule colonne, dans l'idée.

    J'aimerais optimiser au maximum cette requête car la table contiendra potentiellement 1M de lignes. 

    Est-ce que quelqu'un aurait une petite piste pour m'aiguiller ? Peut-être qu'il y a un problème de conception derrière, je suis ouvert à toute proposition.

    Merci d'avance :)

    -
    Edité par Grillaume 11 octobre 2018 à 11:37:36

    • Partager sur Facebook
    • Partager sur Twitter
      11 octobre 2018 à 13:37:58

      Bonjour,

      Ce que tu cherches à faire est une intersection.

      Avec SQL Server, tu peux utiliser requete1 INTERSECT requete2 ...

      Exemple :

      SELECT DISTINCT nom
      FROM matable
      WHERE prenom = 'Pierre'
      
      INTERSECT
      
      SELECT DISTINCT nom
      FROM matable
      WHERE prenom = 'Sylvain'

      Devrait te retourner DUPONT.

      Du coup en fonction de si tu as un ou plusieurs paramètres en entrée, tu rajoutes des INTERSECT ...

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        11 octobre 2018 à 13:52:09

        Merci Benzouye pour ta réponse!

        J'y ai effectivement pensé, mais au niveau des perfs c'est pas terrible si ? Sur 1M de ligne que l'on parcours autant de fois qu'il y a de paramètres (en prenant large je devrais être à une 30aine), ça me semble beaucoup non ? (simple question, je n'ai que très peu de connaissances là dessus).

        Ta proposition suppose que le prénom est systématiquement renseigné, mais dans le cas où il est NULL, c'est également possible d'utiliser INTERSECT de manière conditionnelle (avec un IS NULL sur le paramètre) ?

        • Partager sur Facebook
        • Partager sur Twitter
          11 octobre 2018 à 15:37:55

          Si le prénom est NULL alors c'est que tu n'as pas besoin de INTERSECT ... ce sera un simple SELECT sans deuxième partie ...

          seiyaourt a écrit:

          au niveau des perfs c'est pas terrible si ? Sur 1M de ligne que l'on parcours autant de fois qu'il y a de paramètres (en prenant large je devrais être à une 30aine), ça me semble beaucoup non ?

          De toute façon il faudra parcourir les lignes autant de fois que tu as de paramètres ... sur un million de lignes comme sur une centaine ... pas le choix ...

          Une autre solution réside dans les auto-jointures, mais c'est le même combat ...

          SELECT DISTINCT nom
          FROM
          	matable T1
          		INNER JOIN matable T2
          			ON T1.nom = T2.nom
          WHERE
          	T1.prenom = 'Pierre'
          	AND T2.prenom = 'Sylvain'

          -
          Edité par Benzouye 11 octobre 2018 à 15:38:11

          • Partager sur Facebook
          • Partager sur Twitter
          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
            12 octobre 2018 à 9:33:23

            Pas très fan des auto jointures, j'ai trouvé une autre solution pour faire juste le nombre d'intersects qu'il faut.

            Sinon merci pour l'aide que tu m'as apportée :)

            • Partager sur Facebook
            • Partager sur Twitter

            [MS SERVER] Effectuer des AND sur une même colonne

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown