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

Développement SQL Server Discussion :

PB avec deux Requêtes SQL


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif Avatar de PaulNero
    Homme Profil pro
    DBA Senior Oracle and SQL SERVER
    Inscrit en
    Octobre 2010
    Messages
    416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Inde

    Informations professionnelles :
    Activité : DBA Senior Oracle and SQL SERVER
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2010
    Messages : 416
    Par défaut PB avec deux Requêtes SQL
    Bonjour,
    depuis des années j'utilise cette requête dans un DTS pour me charger des données dans un fichier chaque début du mois.Il charge ainsi les données du mois précédent:

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT numero_cli, nom, prenom,date_encais,numero_cli_fact, date_rembours, num_fact,type_fact from Client inner join facture on Client.numero_cli=facture.numero_cli_fact
    where year(date_encais)=getdate() and
    month(date_encais)=month(getdate())-1
    le soucis c'est qu'au mois de janvier,il devrait me charger les données du mois de décembre de l'année précédente, mais il ne les trouve pas et c'est normal, car getdate() renvoit la date en cours.

    j'ai ainsi opté pour cette procédure T-SQL:

    Code sql : 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
    use madatabase;
    begin
      declare @year_sec date
      declare @month_sec month
    set @year_sec=year(gatdate())
    set @month_sec=month(gatedate())
    if @month_sec=1 
         set @month_sec=12
         set @year_sec= @year_sec -1
         begin
             SELECT numero_cli, nom, prenom,date_encais,numero_cli_fact,
             date_rembours, num_fact,type_fact from Client inner join facture on  
             Client.numero_cli=facture.numero_cli_fact
             where year(date_encais)=@year_sec and
             month(date_encais)=@month_sec
         end
    else
         begin
             SELECT numero_cli, nom, prenom,date_encais,numero_cli_fact,
             date_rembours, num_fact,type_fact from Client inner join facture on  
             Client.numero_cli=facture.numero_cli_fact
             where year(date_encais)=@year_sec and
             month(date_encais)=@month_sec
         end
     
    end

    Pensez vous que cela est optimisé? des idées?

  2. #2
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Pourquoi ne pas faire ceci ?

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT
                     numero_cli, nom, prenom,date_encais,numero_cli_fact, date_rembours, num_fact,type_fact 
    FROM 
            Client INNER JOIN facture ON Client.numero_cli=facture.numero_cli_fact
    WHERE
            date_encais between datediff(month,date_encais,-1) and getdate()
    N.B. : j'ai écrit datediff de tête, la syntaxe est à vérifier.

    Il faudra juste p-e adapter les bornes de l'opérateur between pour correspondre exactement à votre besoin.

  3. #3
    Membre très actif Avatar de PaulNero
    Homme Profil pro
    DBA Senior Oracle and SQL SERVER
    Inscrit en
    Octobre 2010
    Messages
    416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Inde

    Informations professionnelles :
    Activité : DBA Senior Oracle and SQL SERVER
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2010
    Messages : 416
    Par défaut
    Merci de ta participation,
    mais je pense pas que datediff résoudra le problème de janvier!!
    en effet, si je suis le 2 janvier 2013 et que je veuille récupérer les données du mois d'avant, j'ai un getdate() qui me retournera 2013 et si je fais month -1 j'ai "0" donc la requête ne retournera rien du tout.


    cordialement

  4. #4
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Et bien justement non.

    C'est là tout l'intérêt de travailler sur les types de données corrects.

    Tu veux faire un traitement sur une date (obtenir la date un mois avant dans ce cas). Il faut donc travailler avec des dates et les fonctions appropriées.

    La fonction DATEDIFF renverra une date (valide!) qui correspondra à ce qui lui a été passé en paramètre.

    En utilisant la fonction MONTH(qui retourne un entier!), tu sors du "domaine" des dates et obtient donc des résultats farfelus en appliquant des traitements à priori triviaux dessus.

    Tout le monde sait bien que le mois avant janvier est décembre (même les SGDBR) mais si tu lui dis de prendre l'entier avant 1, il est normal qu'il te réponde que c'est 0. J'en ferais de même.

  5. #5
    Membre très actif Avatar de PaulNero
    Homme Profil pro
    DBA Senior Oracle and SQL SERVER
    Inscrit en
    Octobre 2010
    Messages
    416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Inde

    Informations professionnelles :
    Activité : DBA Senior Oracle and SQL SERVER
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2010
    Messages : 416
    Par défaut
    En utilisant la fonction MONTH(qui retourne un entier!), tu sors du "domaine" des dates et obtient donc des résultats farfelus en appliquant des traitements à priori triviaux dessus.
    j'ai beaucoup rigolé je t'assure.
    bon devenons sérieux.

    si je te prends au mot, cela donnerait ceci dans ma requête:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT
                     numero_cli, nom, prenom,date_encais,numero_cli_fact, date_rembours, num_fact,type_fact 
    FROM 
            Client INNER JOIN facture ON Client.numero_cli=facture.numero_cli_fact
    WHERE
            date_encais = datediff(month,date_encais,-1) and 
          date_encais=datediff(year,date_encais,1)

    mais il me semble que si j'exécute ça le 5 du mois par exemple, il me prendra les données entre le 1er et le 5?

    cordialement

  6. #6
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Content de t'avoir fait rire. Il y a 2 ans (avant que je m'investisse personnellement dans l'apprentissage du monde des DB), je faisais comme toi pour ce genre de chose en utilisant la fonction Month et en me faisant ch*** pour gérer les débuts et fin d'années.

    Puis j'ai compris qu'il fallait travailler avec les types de données et depuis, ça va beaucoup mieux.

    Bref, revenons à ton problème.

    Tout d'abord, je tiens à m'excuser car j'ai utilisé la mauvaise fonction... Il s'agit bien sûr de DATEADD et non pas DATEDIFF. DATEDIFF retourne un entier et non pas une date (ce qui fait qu'on retombe dans le genre de cas où ça ne va pas). Il n'empêche que le raisonnement reste le même.

    La clause WHERE telle qu'écrite dans ta requête demande que date_encais soit égale à date_encais avec un mois de moins (pour la première condition).

    Si je caricature un peu, cela revient à écrire On se rend vite compte qu'il y a un souci (mais cela vient p-e de la confusion que j'ai introduite par l'utilisation de la mauvaise fonction).

    Si j'ai bien compris, tu veux donc les lignes dont la valeur de la colonnes date_encais se trouve dans le mois précédent le mois en cours.

    J'écrirais donc une clause WHERE ressemblant (je reste prudent) à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    WHERE
            date_encais between DATEADD(month,-1,@UneDateDeReference) AND @UneDateDeReference
    Si la variable @UneDateDeReference est égale, par exemple, à 20130108 (la date d'aujourd'hui quoi), alors, la condition de la clause where que j'ai écrite sera ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE date_encais between '20121208' and '20130108'
    Reste donc à avoir une date de référence qui fasse en sorte que la requête porte sur le premier du mois précédent jusqu'au premier du mois actuel.

    Je ferais quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    DECLARE @UneDateDeReference DATE;
     
    SET @UneDateDeReference = DATEADD(DAY,-(DAY(GETDATE())-1),GETDATE());
    Suite au prochain message, je n'aime pas les pavés... (et aussi car il faut que je me relise et que c'est plus facile au format forum qu'au format texte)

  7. #7
    Membre très actif Avatar de PaulNero
    Homme Profil pro
    DBA Senior Oracle and SQL SERVER
    Inscrit en
    Octobre 2010
    Messages
    416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Inde

    Informations professionnelles :
    Activité : DBA Senior Oracle and SQL SERVER
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2010
    Messages : 416
    Par défaut
    En utilisant la fonction MONTH(qui retourne un entier!), tu sors du "domaine" des dates et obtient donc des résultats farfelus en appliquant des traitements à priori triviaux dessus.
    j'ai beaucoup rigolé je t'assure.
    bon devenons sérieux.

    si je te prends au mot, cela donnerait ceci dans ma requête:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT
                     numero_cli, nom, prenom,date_encais,numero_cli_fact, date_rembours, num_fact,type_fact 
    FROM 
            Client INNER JOIN facture ON Client.numero_cli=facture.numero_cli_fact
    WHERE
            date_encais = datediff(month,date_encais,-1) and 
          date_encais=datediff(year,date_encais,1)

    mais il me semble que si j'exécute ça le 5 du mois par exemple, il me prendra les données entre le 1er et le 5?

    cordialement

Discussions similaires

  1. [2005] Deux requêtes SQL avec un délai entre les deux
    Par janlouk dans le forum Développement
    Réponses: 4
    Dernier message: 31/12/2014, 15h10
  2. Réponses: 5
    Dernier message: 06/10/2009, 09h37
  3. Réponses: 4
    Dernier message: 11/06/2009, 16h03
  4. [MySQL] Problème avec une requête SQL
    Par chobol dans le forum PHP & Base de données
    Réponses: 12
    Dernier message: 11/05/2006, 12h29
  5. [VB]Problème avec une requête SQL
    Par Tyrael62 dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 18/03/2006, 17h47

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