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

MS SQL Server Discussion :

Récup plusieurs variable sous requête


Sujet :

MS SQL Server

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 21
    Points : 18
    Points
    18
    Par défaut Récup plusieurs variable sous requête
    Bonjour,

    je dispose de deux vues crées avec les requêtes suivantes

    Vue InterPlanning
    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
     
    drop view InterPlanning;
    go
     
    CREATE VIEW InterPlanning AS
    SELECT planning.IdIntervention,
    planning.IdSalarie,
    sal.Nom as NomSalarie,
    sal.Prenom as PrenomSalarie,
    planning.IdPA,
    personne.Nom,
    personne.Prenom,
    personne.Adressel,
    personne.Adressel2,
    personne.CodePostall,
    personne.Villel,
    personne.Telephonel1,
    planning.CodeActivite,
    activite.Libelle,
    planning.DateDebutReelle,
    planning.HeureDebutReelle,
    planning.DateFinReelle,
    planning.HeureFinReelle,
    planning.DateDebut,
    planning.DateFin,
    planning.HeureDebut,
    planning.HeureFin,
    planning.DateAnnuler,
    planning.CodeAsso,
    planning.DateSuppr
    from Salarie sal, PL_Activite activite,PL_Planning planning
    left outer join PA personne
    on personne.CodeEmployeur = planning.IdPA
    and personne.CodeAssociation = planning.CodeAsso
    where planning.DateAnnuler='1901-01-01 00:00:00.000'
    and planning.DateSuppr='1901-01-01 00:00:00.000'
    and planning.IdSalarie = sal.CodeCandidat
    and planning.CodeAsso=sal.CodeAssociation
    and planning.CodeActivite = activite.CodeActivite
    go
    Vue TelephoneActive
    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
     
    drop view TelephoneActive;
    go
     
    CREATE VIEW TelephoneActive AS
    SELECT tel.IMEI,
    tel.ID_TG_Telephone,
    telAut.dateDebut,
    telAut.dateFin,
    telAut.codeSalarie,
    telAut.codeAssociation
    FROM eliad.dbo.TG_Telephone tel,TG_TelephoneAutorisation telAut
    where telAut.dateDebut <= GETDATE()
    and telAut.dateFin>=GETDATE()
    and telAut.ID_TG_Telephone=tel.ID_TG_Telephone;
    go
    pour récupérer les intervention faites par une personne j'exécute cette requête

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Select *
    from InterPlanning
    where IdSalarie=(select codeSalarie from TelephoneActive where IMEI='354956052024481')
    and DATEPART(m, DateDebutReelle) = DATEPART(m, getdate())
    and DATEPART(yy, DateDebutReelle) = DATEPART(yy,getdate());
    elle s'exécute quasiment instantanément , mais le problème c'est que j'aimerais bien filtrer également sur la DateDébutRéelle en utilisant les champs DateDébut et DateFin dans la vue TelephoneActive
    Peut on récupérer plusieurs variables dans ma requête imbriquée ? si non y a t il un autre moyen de faire

    car j'ai fait une autre requête en mettant les deux vues dans le from mais j'ai peur que ça mette trop de temps à s'exécuter car ce n'est plus instantané avec cette autre requête

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Select *
    from InterPlanning planning,TelephoneActive tel
    where DATEPART(m, DateDebutReelle) = DATEPART(m, getdate())
    and DATEPART(yy, DateDebutReelle) = DATEPART(yy,getdate())
    and planning.DateDebutReelle>=tel.dateDebut
    and planning.DateDebutReelle<=tel.dateFin
    and planning.IdSalarie=tel.codeSalarie
    and tel.IMEI='354956052024481';
    s'il n'y a pas d'autre moyens , dois je utiliser une procédure stockée ou une fonction pour retourner mes valeurs ? devrais utiliser des curseurs dans cette fonction pour renvoyer mes valeurs ?

    merci par avance pou vos réponses et si je n'ai pas été assez clair, n'hésitez pas à me demander plus de détails

  2. #2
    Expert éminent
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Points : 6 775
    Points
    6 775
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    Je ne sais pas si ça réponds à ta questions, mais tu pourrais passer par une requête EXISTS.

    un exemple :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT *
      FROM TableA A
     WHERE EXISTS ( SELECT NULL
                      FROM TableB B
                     WHERE A.id = B.fk
                       AND A.date = B.date
                       AND ... = ... );

    EXISTS permet à la requête principale de ne ressortir que les informations présentes dans la sous requête et ayant un critère d'égalité entre les 2. (ici A.id = B.fk AND A.date = B.date)
    Je pense que cela devrait pouvoir t'aider.

    Cordialement,
    Lyche

  3. #3
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Citation Envoyé par Minifish57
    elle s'exécute quasiment instantanément , mais le problème c'est que j'aimerais bien filtrer également sur la DateDébutRéelle en utilisant les champs DateDébut et DateFin dans la vue TelephoneActive
    Peut on récupérer plusieurs variables dans ma requête imbriquée ? si non y a t il un autre moyen de faire

    car j'ai fait une autre requête en mettant les deux vues dans le from mais j'ai peur que ça mette trop de temps à s'exécuter car ce n'est plus instantané avec cette autre requête
    Intuitivement, je dirai que votre première requête est rapide parce que le filtre sur IdSalarie est sélectif : la sous-requête doit ramener peu de lignes, et/ou la colonne IdSalarie est indexée.

    Je crois que votre principale erreur vient des prédicats suivants :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    AND DATEPART(m, DateDebutReelle) = DATEPART(m, getdate())
    AND DATEPART(yy, DateDebutReelle) = DATEPART(yy,getdate());
    Avant d'exécuter une requête, SQL Server calcule un plan d'exécution. Ce calcul est basé sur des statistiques sous-jacentes aux valeurs contenues dans les colonnes et index utilisés par les requêtes soumises par vos applications. Entre autres, ces statistiques contiennent un histogramme qui décrit la répartition des valeurs de la colonne ou de l'index.
    J'insiste sur le mot valeur, car si SQL Server "sait" approximativement quelles valeurs sont dans les colonnes et comment elles sont distribuées, il ne "sait pas" quel nombre de lignes va donc répondre à l'application d'une fonction sur une colonne (sauf si vous disposez d'une colonne calculée, et que vous filtrez par celle-ci).
    Donc il va utiliser des règles d'optimisation par défaut, qui peuvent avoir des conséquences négatives sur les performances de vos requêtes.

    Je réécrirais donc votre prédicat comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    AND	DateDebutReelle BETWEEN DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0) -- premier jour du mois courant, à minuit
    	AND DATEADD(month, DATEDIFF(month, 0, GETDATE()) + 1, 0) -- premier jour du mois suivant, à minuit
    Servez-vous du billet que j'ai écrit sur ce sujet

    La partie droite du prédicat (après le BETWEEN) est calculée à chaque exécution en fonction de la valeur de GETDATE(). La partie gauche du prédicat référence une colonne, donc la statistique sous-jacente à celle-ci est utilisée pour la production d'une estimation de cardinalité précise, et probablement d'un plan de requête plus performant. Il faudrait que vous vous donniez le plan de requête réel pour en être certain. Vérifiez aussi que la colonne DateDebutReelle est indexée.

    @++

  4. #4
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Une première remarque : vos requêtes seraient sans doute plus lisibles en utilisant les jointures normalisées partout plutôt qu'un mélange des genres.

    concernant votre requete, votre filtre est certainement optimisable, surtout si vous disposez d'index sur les dates :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    WHERE DATEPART(m, DateDebutReelle) = DATEPART(m, getdate())
    AND DATEPART(yy, DateDebutReelle) = DATEPART(yy,getdate())
    Vous semblez filtrer pour ne garder que les lignes qui correspondent au mois en cours, mais en mettant une fonction sur votre colonne dans votre filtre, vous obligez le moteur à appliquer la fonction sur toutes les ligne avant de pouvoir évaluer le filtre. Vous devriez donc chercher la date de début de mois pour la comparer à votre colonne date directement :

    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
     
    WHERE DateDebutReelle >=
    	DATEADD(
    		MONTH
    		,DATEDIFF(
    			MONTH
    			,0
    			,CURRENT_TIMESTAMP 
    		) 
    		,0
    	)
    AND DateDebutReelle <
    	DATEADD(
    		MONTH
    		,DATEDIFF(
    			MONTH
    			,0
    			,CURRENT_TIMESTAMP 
    		) + 1
    		,0
    	)

Discussions similaires

  1. Réponses: 1
    Dernier message: 12/01/2012, 12h24
  2. Réponses: 2
    Dernier message: 23/04/2007, 00h10
  3. Sous requetes retourne plusieurs variables
    Par poosh dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 25/08/2006, 09h51
  4. Sous-requête excutée plusieurs fois dans une requête
    Par sheridan31 dans le forum Oracle
    Réponses: 8
    Dernier message: 03/07/2006, 16h18
  5. Ramener plusieurs champs dans une sous requête...
    Par David.V dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 12/01/2005, 07h54

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