Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Hive] left join - conserver un seul match

    14 août 2018 à 10:13:52

    Bonjour,

    Je dois adapter un traitement HQL existant (donc je ne peux pas tout refaire) pour 

    Je souhaite conserver telle quelle ma table A et ajouter un champ qui sera valorisé par une valeur "en dur" si le critère de jointure avec ma table B est rempli au moins une fois.

    Ma table A contient (parmi 125 autres champs) :
    nom
    prenom
    date_saisie

    Ma table B est un référentiel composé de :
    nom
    prenom
    date_reelle

    Le critère de jointure est le suivant : a.nom=b.nom AND a.prenom=b.prenom AND [b.date_reelle - 7 jours <= a.date_saisie <= b.date_reelle + 7 jours]
    On est d'accord que c'est pourri et pas optimisé du tout mais je n'ai pas le choix, le traitement doit prendre en compte les écarts de saisie de la date à +/- 7 jours. Et il n'y a pas d'autre champ permettant de faire le lien.

    Le problème est qu'avec de tels critères une ligne de A peut matcher avec plusieurs ligne de B, or je veux seulement savoir si ça matche au moins une fois et si c'est le cas mettre "x" dans une nouvelle colonne en sortie de la requête (colonne qui restera vide pour les lignes où ça n'a pas matché).


    En résumé je cherche donc comment faire un left join qui ne rajoute pas de ligne dans la table de gauche lorsqu'il y a plusieurs match avec la table de droite.

    Merci d'avance pour votre aide.

    -
    Edité par Laaris 14 août 2018 à 11:40:16

    • Partager sur Facebook
    • Partager sur Twitter
    There must be some way outa here.
      14 août 2018 à 12:57:00

      Si je comprend bien:

      - si il n'y a pas de jointure, (valeur de TABLEB à NULL) on doit afficher la ligne

      - si il y a UNE seule jointure, on doit afficher la ligne

      - Si il y a PLUSIEURS jointures, on ne doit PAS afficher la ligne.

      Voici la requète à ces critères :

      SELECT a.nom, a.prenom, COUNT(b.*)
      FROM TABLEA as a
        LEFT OUTER JOIN TABLEB as b
          ON a.nom = b.nom AND a.prenom = b.prenom AND ...
      GROUP BY a.nom, a.prenom
      HAVING COUNT(b.*) > 0


      On est bien d'accord que la modélisation de cette base de donnés est pourrie... Mais ce n'est pas une raison pour en rajouter encore un peu plus !

      Plutôt que de créer une colonne qui ne serait remplies que dans certaines conditions (et donc avec plein de valeurs à NULL), crée plutôt une table supplémentaire (avec une vraie jointure sur la table A) pour ces nouvelles valeurs.

      Enfin, l'utilisation de HQL n'est pas une entrave à la bonne normalisation de la base de données. Il suffit de créer les bonnes tables (jusqu'au respect de la 3e forme normale), de les remplir à partir des table A et B. Enfin on supprime ces tables immondes, et on les remplace par des VUES (avec des triggers INSERT / UPDATE / DELETE pour renvoyer les opérations d'écritures sur les bonnes tables).

      Ainsi, l'utilisation sera transparente pour HQL, et il n'y aura pas une seule ligne à modifier dans le code de l'application.

      Non seulement on y gagne en lisibilité, en facilité de maintenance pour l'avenir, mais aussi en performance (parce que là cette jointure, elle va plomber les perf des que la taille de la BDD va dépasser la quantité de RAM disponible) !

      • Partager sur Facebook
      • Partager sur Twitter
        16 août 2018 à 9:48:08

        Disons que j'ai largement simplifié.

        Ma jointure doit s'intégrer dans une grosse requête existante qui tape déjà sur plusieurs tables. 

        Et j'ajoute une nouvelle colonne en sortie car le fait qu'elle soit renseignée ou non va être utilisé dans une condition pour valoriser une autre colonne.

        Sans rentrer dans les détails fonctionnels, le fait qu'on trouve ou non une ligne dans la table B qui matche sur nom et prénom avec date à +/-7 jours n'est qu'un critère parmi d'autres utilisé pour le calcul d'un indicateur stocké dans une autre colonne en sortie de la requête.

        PI ces tables ne sont que des tables temporaires utilisées pour agréger des données et calculer des indicateurs dans un traitement batch, elles sont supprimées en fin de traitement pour ne garder que les tables finales (construites au terme d'un traitement de plusieurs heures) qui sont accédées par l'appli.

        -
        Edité par Laaris 16 août 2018 à 10:21:05

        • Partager sur Facebook
        • Partager sur Twitter
        There must be some way outa here.

        [Hive] left join - conserver un seul match

        × 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