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

Requêtes PostgreSQL Discussion :

Clause WHERE dynamique


Sujet :

Requêtes PostgreSQL

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    212
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2009
    Messages : 212
    Points : 71
    Points
    71
    Par défaut Clause WHERE dynamique
    Bonjour à tous ,
    Je coince depuis quelques heures sur un problème:

    Je reçois en filtre 2 dates : date début - date fin
    - Je dois récupérer les données dans ce range de date et également un historique des années précédantes dans ce même range (mois-jour)
    Exemple : 03/08/2010 - 23/12/2010 avec historique sur 2 ans:

    Je veux les données de :
    03/08/2010 - 23/12/2010 +
    03/08/2009 - 23/12/2009 +
    03/08/2008 - 23/12/2008

    J'aimerais éviter les fonctions, la récursivité, si possible.

    Quelqu'un aurait une idée???
    Merci d'avance ,
    Vinc

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Si le nombre d'années en arrière est fixe (2) le problème est simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    WHERE date BETWEEN debut AND Fin
    OR date BETWEEN debut-'1 year'::interval AND fin-'1 year'::interval
    OR date BETWEEN debut-'2 years'::interval AND fin-'2 years'::interval

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    212
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2009
    Messages : 212
    Points : 71
    Points
    71
    Par défaut
    Salut,
    Non justement il n'est pas fixe. c'est une variable

  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 solution pas très jolie et surtout non sargable, mais j'ai pas mieux sous la main.

    C'est à adapter/améliorer, je ne connais pas la syntaxe de postgre, mais le principe doit être bon : "tronquer" les années des dates, pour tout ramener à l'an 1, et comparer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    WHERE
        date - CAST(CAST(EXTRACT(YEAR FROM date) AS VARCHAR(9)) || ' YEAR' AS INTERVAL) 
        BETWEEN 
            debut - CAST(CAST(EXTRACT(YEAR FROM debut) AS VARCHAR(9)) || ' YEAR' AS INTERVAL)
        AND
            fin- CAST(CAST(EXTRACT(YEAR FROM fin) AS VARCHAR(9)) || ' YEAR' AS INTERVAL)
     
    AND date > debut - interval ('2 year')

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    212
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2009
    Messages : 212
    Points : 71
    Points
    71
    Par défaut
    Merci beaucoup aieeuuuuuuuuuuu
    C'est bon ça fonctionne !

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Une autre méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CROSS JOIN (select generate_series(0,2) as nb) as gs
         WHERE date BETWEEN debut - interval '1 year' * gs.nb
                        AND fin   - interval '1 year' * gs.nb

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    212
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2009
    Messages : 212
    Points : 71
    Points
    71
    Par défaut
    Salut,
    J'ai un nouveau problème.
    J'ai utilisé la solution de aieuuuuuuu.
    Quid lorsque la date de début est par exemple 31/12/2011
    et que la date de fin est 01/06/2012 ?

    ==> Lorsque l'on travaille sur 2 années

    Voici le morceau de query:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    WHERE ("DateCreation" - CAST(CAST(TO_CHAR("DateCreation",'YYYY') AS INTEGER) || 'YEAR' AS INTERVAL)
    	 BETWEEN CAST('31/12/2011' AS DATE) - CAST(CAST(TO_CHAR(CAST('31/12/2011' AS DATE),'YYYY') AS INTEGER) || 'YEAR' AS INTERVAL)
    	 AND CAST('30/06/2012' AS DATE) - CAST(CAST(TO_CHAR(CAST('30/06/2012' AS DATE),'YYYY') AS INTEGER) || 'YEAR' AS INTERVAL))
    Du coup, et c'est logique , je n'ai aucune donnée en sortie.
    Les paramètres:

    Date de début de période : 01/09/2011
    Date de fin de période : 31/12/2011
    Date de début de visite : 01/06/2012
    date de fin de visite : 30/06/2012
    Nombre d'années d'historique :2

    Requête complète :
    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
    SELECT CAST (TO_CHAR("DateDebutPrestation",'YYYY') AS INTEGER) AS ANNEE,
    	 COUNT('PK_ID_DOSSIER') AS NBREDOSSIER,
    	 SUM("NbreEffectif") AS NBREEFFECTIF
    	 FROM "table"
    	 WHERE ("DateCreation" - CAST(CAST(TO_CHAR("DateCreation",'YYYY') AS INTEGER) || 'YEAR' AS INTERVAL)
    	 BETWEEN CAST('31/12/2011' AS DATE) - CAST(CAST(TO_CHAR(CAST('31/12/2011' AS DATE),'YYYY') AS INTEGER) || 'YEAR' AS INTERVAL)
    	 AND CAST('30/06/2012' AS DATE) - CAST(CAST(TO_CHAR(CAST('30/06/2012' AS DATE),'YYYY') AS INTEGER) || 'YEAR' AS INTERVAL))
    	 AND ("DateCreation" > (CAST('31/12/2011' AS DATE)- CAST('2 year' AS INTERVAL)))
    	 AND ("DateCreation" < CAST('30/06/2012' AS DATE))
    	 AND ("DateDebutPrestation" - CAST(CAST(TO_CHAR("DateDebutPrestation",'YYYY') AS INTEGER) || 'YEAR' AS INTERVAL)
    	 BETWEEN CAST('01/06/2012' AS DATE) - CAST(CAST(TO_CHAR(CAST('01/06/2012' AS DATE),'YYYY') AS INTEGER) || 'YEAR' AS INTERVAL)
    	 AND CAST('30/06/2012' AS DATE) - CAST(CAST(TO_CHAR(CAST('30/06/2012' AS DATE),'YYYY') AS INTEGER) || 'YEAR' AS INTERVAL))
    	 AND ("DateDebutPrestation" > (CAST('01/06/2012' AS DATE)- CAST('2 year' AS INTERVAL)))
    	 AND ("DateDebutPrestation" < CAST('30/06/2012' AS DATE))
    	 GROUP BY ANNEE
    	 ORDER BY ANNEE;
    Quelqu'un aurait-il une idée?

  8. #8
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 761
    Points : 52 547
    Points
    52 547
    Billets dans le blog
    5
    Par défaut
    Utilisez la solution de Waldar;

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    212
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2009
    Messages : 212
    Points : 71
    Points
    71
    Par défaut
    En effet cela semble bien mieux fonctionner avec cette solution merci beaucoup à Waldar ! (Et également à SQLpro pour m'avoir rappelé d'ouvrir les yeux )

  10. #10
    Membre expert
    Avatar de alassanediakite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Mali

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 1 599
    Points : 3 590
    Points
    3 590
    Billets dans le blog
    8
    Par défaut
    Salut
    La solution de Waldar résout-elle...
    Citation Envoyé par vinch999 Voir le message
    Non justement il n'est pas fixe. c'est une variable
    Si non, pourquoi avoir sauté celle de estofilo?
    @+
    Le monde est trop bien programmé pour être l’œuvre du hasard…
    Mon produit pour la gestion d'école: www.logicoles.com

  11. #11
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Oui, dans le generate_series, il faut remplacer le 2 par le nombre d'années désiré.

  12. #12
    Membre expert
    Avatar de alassanediakite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Mali

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 1 599
    Points : 3 590
    Points
    3 590
    Billets dans le blog
    8
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Oui, dans le generate_series, il faut remplacer le 2 par le nombre d'années désiré.
    C'est pareil pour estofilo!!!
    @+
    Le monde est trop bien programmé pour être l’œuvre du hasard…
    Mon produit pour la gestion d'école: www.logicoles.com

  13. #13
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Justement non, c'est même clairement dit par estofilo :
    Si le nombre d'années en arrière est fixe
    Si vous voulez cinq ans d'historique, en utilisant la solution d'estofilo il faudrait écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    WHERE date BETWEEN debut AND Fin
    OR date BETWEEN debut-'1 year'::interval AND fin-'1 year'::interval
    OR date BETWEEN debut-'2 years'::interval AND fin-'2 years'::interval
    OR date BETWEEN debut-'3 years'::interval AND fin-'3 years'::interval
    OR date BETWEEN debut-'4 years'::interval AND fin-'4 years'::interval
    OR date BETWEEN debut-'5 years'::interval AND fin-'5 years'::interval
    Ce qui est un peu moins dynamique que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CROSS JOIN (SELECT generate_series(0,5) AS nb) AS gs
         WHERE date BETWEEN debut - interval '1 year' * gs.nb
                        AND fin   - interval '1 year' * gs.nb

  14. #14
    Membre expert
    Avatar de alassanediakite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Mali

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 1 599
    Points : 3 590
    Points
    3 590
    Billets dans le blog
    8
    Par défaut
    Salut

    En fait je pensais à...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE date BETWEEN debut AND fin-'x year'::interval
    @+
    Le monde est trop bien programmé pour être l’œuvre du hasard…
    Mon produit pour la gestion d'école: www.logicoles.com

  15. #15
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Mais ça n'aurait plus rien à voir avec le besoin initial.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. BETWEEN dynamique dans la clause WHERE
    Par Maniz dans le forum Langage SQL
    Réponses: 4
    Dernier message: 27/06/2012, 15h30
  2. Requete avec clause where dynamique
    Par shyangel dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 19/05/2011, 13h10
  3. [Linq to SQL] Clause Where dynamique
    Par Kamishu dans le forum Accès aux données
    Réponses: 2
    Dernier message: 14/08/2008, 14h17
  4. [LINQ To SQL] Clauses WHERE dynamiques
    Par SaumonAgile dans le forum Accès aux données
    Réponses: 7
    Dernier message: 23/02/2008, 01h11
  5. [EJBQL] [EJB2] Clause WHERE Dynamique
    Par ALX79 dans le forum Java EE
    Réponses: 1
    Dernier message: 18/10/2007, 14h09

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