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

Langage SQL Discussion :

Between sur des date vides


Sujet :

Langage SQL

  1. #1
    Modérateur
    Avatar de Kreepz
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2011
    Messages : 681
    Points : 1 458
    Points
    1 458
    Billets dans le blog
    1
    Par défaut Between sur des date vides
    Bonjour,

    Je dois effectuer une requête qui me récupère un contrat suivant une date. Cette date doit être comprise soit entre la date_effet_crt et date_fin_crt OU la date_effet_tech et la date_fin_tech (ces deux dates appartiennent à la table des intervenants) et tout cela par rapport à un nm_identif que je récupère avant.

    Voici ma requête, j'ai essayé plusieurs méthodes mais sans succès...

    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
     
    SELECT DISTINCT F_CRT_CONTRAT.NM_CODI_CONTRAT, PERSONNE.NOM, PERSONNE.PRENOM, ADRESSE, CODE_POSTAL, VILLE, IBAN, ADRESSE_BANCAIRE, CH_TITULAIRE
     
    FROM F_CRT_CONTRAT, F_CRT_INTERVENANT, PERSONNE, F_CRT_ASSURE_BENEFICIAIRE
     
    LEFT OUTER JOIN ADR_POST ON (F_CRT_ASSURE_BENEFICIAIRE.NM_IDENTIF_ASSURE = ADR_POST.NM_IDENTIF_PERSONNE)
    LEFT OUTER JOIN ADR_BAN ON (F_CRT_ASSURE_BENEFICIAIRE.NM_IDENTIF_ASSURE = ADR_BAN.NM_IDENTIF_PERSONNE)
     
    WHERE F_CRT_CONTRAT.NM_CODI_CONTRAT = F_CRT_INTERVENANT.NM_CODI_CONTRAT
    AND F_CRT_INTERVENANT.NM_IDENTIF = F_CRT_ASSURE_BENEFICIAIRE.NM_IDENTIF_ASSURE
    AND F_CRT_ASSURE_BENEFICIAIRE.NM_IDENTIF_BENEFICIAIRE = PERSONNE.NM_IDENTIF_PERSONNE
     
    AND NM_STATUT_CRT = 1
    AND (NM_CODI_PRODUIT = 4 OR NM_CODI_PRODUIT = 5)
     
    AND ('13/04/2014' BETWEEN F_CRT_INTERVENANT.DT_EFFET_TECH AND F_CRT_INTERVENANT.DT_FIN_TECH
    OR '13/04/2014' BETWEEN F_CRT_CONTRAT.DT_EFFET_CRT AND F_CRT_CONTRAT.DT_FIN_CRT)
     
    AND PERSONNE.NM_IDENTIF_PERSONNE = '1170824'
     
    ;
    Le problème est que dans la table F_CRT_CONTRAT la date de fin est souvent remplie à 31/12/999 et dans F_CRT_INTERVENANT quand un contrat n'est pas terminé la DT_FIN_TECH est vide donc mon between ne s'effectue pas...

    J'espère avoir été clair?

    Merci

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 898
    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 898
    Points : 53 136
    Points
    53 136
    Billets dans le blog
    6
    Par défaut
    Utilisez COALESCE pour forcer une date future dans vos colonnes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    AND ('13/04/2014' 
         BETWEEN F_CRT_INTERVENANT.DT_EFFET_TECH 
             AND COALESCE(F_CRT_INTERVENANT.DT_FIN_TECH, '9999-12-31')
     OR '13/04/2014' 
         BETWEEN F_CRT_CONTRAT.DT_EFFET_CRT 
             AND COALESCE(F_CRT_CONTRAT.DT_FIN_CRT, '9999-12-31'))
    A +

  3. #3
    Modérateur
    Avatar de Kreepz
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2011
    Messages : 681
    Points : 1 458
    Points
    1 458
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Utilisez COALESCE pour forcer une date future dans vos colonnes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    AND ('13/04/2014' 
         BETWEEN F_CRT_INTERVENANT.DT_EFFET_TECH 
             AND COALESCE(F_CRT_INTERVENANT.DT_FIN_TECH, '9999-12-31')
     OR '13/04/2014' 
         BETWEEN F_CRT_CONTRAT.DT_EFFET_CRT 
             AND COALESCE(F_CRT_CONTRAT.DT_FIN_CRT, '9999-12-31'))
    Bonjour, merci de votre réponse mais cela ne fonctionne pas ; mes champs Date sont au format date et la fonction COALESCE retourne un CHAR.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ORA-00932: types de données incohérents ; attendu : DATE ; obtenu : CHAR

  4. #4
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 108
    Points : 28 416
    Points
    28 416
    Par défaut
    Il te suffit de proposer des dates en valeurs par défaut...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    COALESCE(F_CRT_INTERVENANT.DT_FIN_TECH, CAST('9999-12-31' AS DATE))

  5. #5
    Modérateur
    Avatar de Kreepz
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2011
    Messages : 681
    Points : 1 458
    Points
    1 458
    Billets dans le blog
    1
    Par défaut
    Les résultats ne sont pas ce que je souhaite

    J'ai ma table F_CRT_CONTRAT

    CODI_CONTRAT | DT_EFFET_CRT | DT_FIN_CRT
    00231563 | 01/01/2014 | 31/12/9999


    Puis ma table F_CRT_INTERVENANT

    CODI_CONTRAT | NM_IDENTIF | DT_EFFET_TECH | DT_FIN_TECH
    00231563 | 11751123645 | 01/01/2014 | 09/04/2014

    Et avec cette requê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
    17
    18
    19
    20
    21
    22
    23
     
    SELECT DISTINCT F_CRT_CONTRAT.NM_CODI_CONTRAT, PERSONNE.NOM, PERSONNE.PRENOM, ADRESSE, CODE_POSTAL, VILLE, IBAN, ADRESSE_BANCAIRE, CH_TITULAIRE
     
    FROM F_CRT_CONTRAT, F_CRT_INTERVENANT, PERSONNE, F_CRT_ASSURE_BENEFICIAIRE
     
    LEFT OUTER JOIN ADR_POST ON (F_CRT_ASSURE_BENEFICIAIRE.NM_IDENTIF_ASSURE = ADR_POST.NM_IDENTIF_PERSONNE)
    LEFT OUTER JOIN ADR_BAN ON (F_CRT_ASSURE_BENEFICIAIRE.NM_IDENTIF_ASSURE = ADR_BAN.NM_IDENTIF_PERSONNE)
     
     
    WHERE F_CRT_CONTRAT.NM_CODI_CONTRAT = F_CRT_INTERVENANT.NM_CODI_CONTRAT
    AND F_CRT_INTERVENANT.NM_IDENTIF = F_CRT_ASSURE_BENEFICIAIRE.NM_IDENTIF_ASSURE
    AND F_CRT_ASSURE_BENEFICIAIRE.NM_IDENTIF_BENEFICIAIRE = PERSONNE.NM_IDENTIF_PERSONNE
     
    AND NM_STATUT_CRT = 1
    AND (NM_CODI_PRODUIT = 4 OR NM_CODI_PRODUIT = 5)
     
    AND ('14/04/2014' 
         BETWEEN F_CRT_INTERVENANT.DT_EFFET_TECH AND COALESCE(F_CRT_INTERVENANT.DT_FIN_TECH, CAST('9999-12-31' AS DATE))
    OR '14/04/2014' 
         BETWEEN F_CRT_CONTRAT.DT_EFFET_CRT AND COALESCE(F_CRT_CONTRAT.DT_FIN_CRT, CAST('9999-12-31' AS DATE)))
     
    AND PERSONNE.NM_IDENTIF_PERSONNE = '1170826'
    ;
    Elle me renvoie tout de même les informations de l'intervenant alors que la date '14/04/2014' n'est pas comprise entre la date_effet_tech et date_fin_tech de l'intervenant..

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 898
    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 898
    Points : 53 136
    Points
    53 136
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par Ozeil Voir le message
    Bonjour, merci de votre réponse mais cela ne fonctionne pas mais champs Date sont au format date et la fonction COALESCE retourne un CHAR.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ORA-00932: types de données incohérents ; attendu : DATE ; obtenu : CHAR
    Non en principe la fonction COALESCE, prend toujours le type de donnée de la colonne si une colonne est précisée...
    Quel est votre SGBDR ?

  7. #7
    Modérateur
    Avatar de Kreepz
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2011
    Messages : 681
    Points : 1 458
    Points
    1 458
    Billets dans le blog
    1
    Par défaut
    Je travaille sur Oracle et utilise toad pour les requêtes et autres.

  8. #8
    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
    Citation Envoyé par SQLpro Voir le message
    Non en principe la fonction COALESCE, prend toujours le type de donnée de la colonne si une colonne est précisée...
    Quel est votre SGBDR ?
    Je dirais plutôt qu'elle prend le type ayant la plus forte priorité, qu'il s'agisse de colonne (avec donc un type explicite) ou d'un littéral (avec donc un type implicite).
    Cela dit ici, le résultat est le même, c'est bien un DATETIME qui devrait ressortir. Mais a mon avis, les colonnes contenant des dates sont certainement de type chaine de caractère, ce qui expliquerait le comportement décrit...

  9. #9
    Modérateur
    Avatar de Kreepz
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2011
    Messages : 681
    Points : 1 458
    Points
    1 458
    Billets dans le blog
    1
    Par défaut
    C'est bon ma requête me renvoie les bons résultats:

    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
     
    SELECT DISTINCT F_CRT_CONTRAT.NM_CODI_CONTRAT, PERSONNE.NOM, PERSONNE.PRENOM, ADRESSE, CODE_POSTAL, VILLE, IBAN, ADRESSE_BANCAIRE, CH_TITULAIRE
     
    FROM F_CRT_CONTRAT, F_CRT_INTERVENANT, PERSONNE, F_CRT_ASSURE_BENEFICIAIRE
     
    LEFT OUTER JOIN ADR_POST ON (F_CRT_ASSURE_BENEFICIAIRE.NM_IDENTIF_ASSURE = ADR_POST.NM_IDENTIF_PERSONNE)
    LEFT OUTER JOIN ADR_BAN ON (F_CRT_ASSURE_BENEFICIAIRE.NM_IDENTIF_ASSURE = ADR_BAN.NM_IDENTIF_PERSONNE)
     
    WHERE F_CRT_CONTRAT.NM_CODI_CONTRAT = F_CRT_INTERVENANT.NM_CODI_CONTRAT
    AND F_CRT_INTERVENANT.NM_IDENTIF = F_CRT_ASSURE_BENEFICIAIRE.NM_IDENTIF_ASSURE
    AND F_CRT_INTERVENANT.NM_IDENTIF = F_CRT_ASSURE_BENEFICIAIRE.NM_IDENTIF_BENEFICIAIRE
    AND F_CRT_ASSURE_BENEFICIAIRE.NM_IDENTIF_BENEFICIAIRE = PERSONNE.NM_IDENTIF_PERSONNE
     
    AND NM_STATUT_CRT = 1
    AND (NM_CODI_PRODUIT = 4 OR NM_CODI_PRODUIT = 5)
     
    AND '01/04/2014' BETWEEN F_CRT_INTERVENANT.DT_EFFET_TECH AND NVL(F_CRT_INTERVENANT.DT_FIN_TECH, CURRENT_DATE)
    AND '01/04/2014' BETWEEN F_CRT_CONTRAT.DT_EFFET_CRT AND F_CRT_CONTRAT.DT_FIN_CRT
     
    AND PERSONNE.NM_IDENTIF_PERSONNE = '1170824'
     
    ;
    Merci pour votre aide!

  10. #10
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Citation Envoyé par Ozeil Voir le message
    Elle me renvoie tout de même les informations de l'intervenant alors que la date '14/04/2014' n'est pas comprise entre la date_effet_tech et date_fin_tech de l'intervenant..
    En effet, mais elle est bien comprise entre DT_EFFET_CRT et DT_FIN_CRT de la table F_CRT_CONTRAT.
    Vous avez mis un OR dans ce critère, dès qu'un l'une ou l'autre des conditions est remplie la ligne est retournée.

    Edit : vous avez modifié votre requête entre le moment où j'ai affiché le sujet et celui où j'ai répondu.

    Vous avez par contre plusieurs coquilles à corriger :
    • Mélange des syntaxes des jointures => développement non homogène
    • Comparaison d'une chaîne de caractères avec des dates => conversion implicite
    • Un distinct dont on ne sait pas trop pourquoi il est là => mon petit doigt mise sur une requête type EXISTS
    • La plupart des colonnes non préfixées par les noms de tables - ou mieux des alias => impossible de savoir qui appartient à quoi et par conséquent de valider ou d'invalider le point précédent.

  11. #11
    Modérateur
    Avatar de Kreepz
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2011
    Messages : 681
    Points : 1 458
    Points
    1 458
    Billets dans le blog
    1
    Par défaut
    J'ai peut-être été un peu vite sur le "Résolu"...

    J'ai effectué des tests et malheureusement j'ai toujours un problème...

    Donc j'ai mes tables:

    F_CRT_CONTRAT

    CODI_CONTRAT | DT_EFFET_CRT | DT_FIN_CRT|...
    00231563 | 01/01/2014 | 31/12/9999


    Puis ma table F_CRT_INTERVENANT

    CODI_CONTRAT | NM_IDENTIF | DT_EFFET_TECH | DT_FIN_TECH |...
    00231563 | 1170824 | 01/01/2014 | 09/04/2014 | l'assuré principal
    00231563 | 1170826 | 01/01/2014 | (pas de date) | un bénéficiaire

    Normalement si je recherche par rapport à l'id du bénéficiaire (1170826) vu que l'assuré principal a une date de fin technique plus aucuns bénéficiaire ne devrais être sur le contrat. Mais quand je fais ma requê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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    SELECT DISTINCT F_CRT_CONTRAT.NM_CODI_CONTRAT, PERSONNE.NOM, PERSONNE.PRENOM, ADR_POST.ADRESSE, ADR_POST.CODE_POSTAL, ADR_POST.VILLE, ADR_BAN.IBAN, ADR_BAN.ADRESSE_BANCAIRE, ADR_BAN.CH_TITULAIRE
     
     
    FROM PERSONNE, F_CRT_INTERVENANT, F_CRT_ASSURE_BENEFICIAIRE
     
     
    LEFT OUTER JOIN ADR_POST ON (F_CRT_ASSURE_BENEFICIAIRE.NM_IDENTIF_ASSURE = ADR_POST.NM_IDENTIF_PERSONNE)
    LEFT OUTER JOIN ADR_BAN ON (F_CRT_ASSURE_BENEFICIAIRE.NM_IDENTIF_ASSURE = ADR_BAN.NM_IDENTIF_PERSONNE)
    LEFT OUTER JOIN F_CRT_CONTRAT ON (F_CRT_ASSURE_BENEFICIAIRE.NM_CODI_CONTRAT = F_CRT_CONTRAT.NM_CODI_CONTRAT)
     
    WHERE PERSONNE.NM_IDENTIF_PERSONNE = F_CRT_INTERVENANT.NM_IDENTIF
    AND F_CRT_INTERVENANT.NM_CODI_CONTRAT = F_CRT_CONTRAT.NM_CODI_CONTRAT
    AND F_CRT_ASSURE_BENEFICIAIRE.NM_IDENTIF_BENEFICIAIRE = PERSONNE.NM_IDENTIF_PERSONNE
     
     
    AND F_CRT_CONTRAT.NM_STATUT_CRT = 1
    AND (F_CRT_CONTRAT.NM_CODI_PRODUIT = 4 OR F_CRT_CONTRAT.NM_CODI_PRODUIT = 5)
     
     
    AND '01/04/2014' BETWEEN F_CRT_INTERVENANT.DT_EFFET_TECH AND NVL(F_CRT_INTERVENANT.DT_FIN_TECH, CURRENT_DATE)
    AND '01/04/2014' BETWEEN F_CRT_CONTRAT.DT_EFFET_CRT AND NVL(F_CRT_CONTRAT.DT_FIN_CRT, CURRENT_DATE)
     
     
    AND PERSONNE.NM_IDENTIF_PERSONNE = '1170826'
     
    ;
    Il me renvoie les informations de l'id 1170826 alors que je ne devrais rien avoir!

Discussions similaires

  1. requete sql avec between sur des champs de type Date
    Par ersoufiane dans le forum Langage SQL
    Réponses: 2
    Dernier message: 02/08/2006, 19h43
  2. [VB6] Requêtes en BDD sur des dates
    Par pom dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 22/11/2005, 14h04
  3. Index sur des dates?
    Par nicovmd dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 30/06/2005, 14h20
  4. analyse "périodes" basées sur des dates.
    Par Yorglaa dans le forum Oracle
    Réponses: 7
    Dernier message: 22/12/2004, 11h39
  5. Réponses: 9
    Dernier message: 17/01/2004, 10h51

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