Aide structure requête

Aide structure requête - SQL/NoSQL - Programmation

Marsh Posté le 12-04-2010 à 10:10:32    

Bonjour,
 
Je fais appel à votre expérience pour savoir comment structurer au mieux ma requête SQL.
 
Considerons 2 objets : Entreprise et Employe. Une entreprise contient plusieurs employes.
Je veux pouvoir recuperer une grappe d'objets Entreprise avec tous ses employés à l'aide de critères portant à la fois sur les entreprises et sur les employes
 
Mes objets
Pour simplifier le problème, disons qu'une Entreprise est entierement caractérisée par sa taille et qu'un Employe est entierement caractérisé par son âge
 
Mes tables
ENTREPRISE contient une TAILLE et un ID
EMPLOYE contient un AGE, et un ID_ENTREPRISE
 
Mon critère de recherche
Je veux récupérer une entreprise de taille >T et dont au moins un employe a un âge > A
 
Un exemple
Entreprise E1 : 3 employes
Employe A: 30 ans
Employe B: 40 ans
Employe C: 50 ans
 
Entreprise E2 : 3 employes
Employe D: 25 ans
Employe E: 28 ans
Employe F: 45 ans
 
Pour une recherche d'une entreprise de  taille 3 avec un employe > 40 ans, je veux recuperer la grappe complete E1 + E2(Entreprises + TOUS leurs employes, meme ceux dont l'âge ne matche pas)-> 6 Rows.
Pour une recherche d'une entreprise de taille 4 avec un employe > 30 ans, je ne veux rien récupérer (parce que la taille de l'entreprise ne matche pas)
 
La difficulté est qu'il me semble qu'il faille faire la requête en deux temps:
-d'abord, récupérer la liste des ID_ENTREPRISE concernés
-ensuite, récupérer la liste des employés concernés par ces ID_ENTREPRISE
 
Autre difficulté:
-Ma vraie table contient en fait des critères plus complexes (dont plusieurs clauses LIKE, c'est gourmand?)
-Ma vraie table contiendra des millions d'entrées, il me faut donc vraiment optimiser ma recherche. Je voudrais donc filtrer un max avant de faire un join entre ma table ENTREPRISE et ma table EMPLOYE. (c'est possible de mettre une clause WHERE dans un JOIN?)


Message édité par liouan le 12-04-2010 à 10:34:24
Reply

Marsh Posté le 12-04-2010 à 10:10:32   

Reply

Marsh Posté le 12-04-2010 à 10:30:46    

Pour ta requete tu peux faire comme ca:

Code :
  1. SELECT E2.*, Emp2.*
  2. FROM Entreprise E1
  3.  JOIN Entreprise E2 ON E1.ID = E2.ID
  4.  JOIN Employe Emp1 ON Emp1.ID_ENTREPRISE = E1.ID
  5.  JOIN Employe Emp2 ON Emp2.ID_ENTREPRISE = E2.ID
  6. WHERE E1.TAILLE = 3 AND Emp1.Age > 40


 
Point de vue performance tu peux utiliser un LIKE tant que tu as un index sur la colonne et que ton LIKE n'est pas du style LIKE '%xxx'.
Tu peux mettre un Where dans ton Join (avec AND et OR) mais ce n'est pas necessaire, l'optimiseur devrai arriver a tout filtrer correctement avant de faire le Join.

Reply

Marsh Posté le 12-04-2010 à 10:54:58    

Désolé, mais je ne suis pas fort en base de données, du coup, je vais te poser une question de debutant :p
 
Dans ta requête, je ne comprends pas ce que fait la jointure de la table ENTREPRISE sur elle même. Peux-tu expliciter?
 
Au sujet des clauses LIKE, malheureusement, je risque d'avoir des clauses LIKE '%' car j'ai une requête préparée. Ce champ est réservé, que l'utilisateur le renseigne ou non. Par contre, je peux les mettre en fin de requête.

Reply

Marsh Posté le 12-04-2010 à 11:09:10    

Je cherche dans le couple Entreprise1/Employe1 une entreprise qui a X TAILLE et au moins un employé > Y AGE, si je me limite a ca j'aurai comme resultat uniquement les employés qui sont un AGE > Y (et pas les autres).
Pour avoir tout le monde je refais un Join sur Entreprise2 et sur Employe2 et je les affiche.
 
Pour le LIKE '%' c'est un tueur de DB, ca va faire un table scan complet a chaque requete, si ta table fait 10Go, ca va faire au moins 10Go de lecture a chaque fois.
C'est quelque chose a eviter a tout prix. Un like 'xx%yy' ca va, mais il ne faut jamais commencer ton LIKE avec un %.
Une requete préparée n'est pas une raison valable pour risquer de finir avec un LIKE '%' (sauf si c'est réelement ce que l'utilisateur veut).

Reply

Marsh Posté le 12-04-2010 à 11:49:25    

Je pense que j'ai compris pour la structure de la requête :)
 
En ce qui concerne les clauses LIKE, je te fais confiance, je vais donc plutôt construire ma requête dynamiquement à base de  
if(critere != NULL)
{
    query+=" AND criterie LIKE :critere";
    query.setParameter("critere",critere);
}
 
Je pense que ça sera nikel,
Un grand merci :)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed