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 :

Enregistrement le plus proche de la date


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    175
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 175
    Points : 106
    Points
    106
    Par défaut Enregistrement le plus proche de la date
    Bonjour,

    J'ai une table qui contient un Id, une valeur et une date.

    Je voudrais remonter l'ensemble de mes Id, valeur pour la date inférieur ou égale la plus proche d'une date passée en paramètre.

    ID Val Date
    1 50 10/10/2008
    1 34 01/09/2008
    2 23 05/10/2008
    2 45 02/07/2008
    3 23 09/10/2008

    je veux avoir pour la date 01/09/2008
    ID Val Date
    1 34 01/09/2008
    2 45 02/07/2008

    Quelle requête dois je réaliser ?

  2. #2
    jnore
    Invité(e)
    Par défaut
    essair ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     
    SELECT id,valeur
    FROM table
    WHERE date<='2008-09-01'

  3. #3
    Membre régulier
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    175
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 175
    Points : 106
    Points
    106
    Par défaut
    non, ça ressemble plus à cela
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT *
    FROM MATABLE a
    WHERE a.MADate = (SELECT max(b.MADate) 
                         FROM MATABLE b 
                         WHERE b.MADate<= :MaDateParam)
    Mais cela remonte plusieurs enregistrement si j'ai plusieurs fois la même date pour un même id.

    J'ai fais différement mais la requête tourne toujours.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT *
    FROM MATABLE a
    WHERE a.Id = (SELECT Top 1 b.Id
                         FROM MATABLE b 
                         WHERE b.MADate<= :MaDateParam
                         order by b.MADate desc, AutreCritere pour choix dans une même date)
    (sqlserver)

  4. #4
    jnore
    Invité(e)
    Par défaut
    Excuse moi, mais tes propositions ne correspondent pas à tes attentes:

    Dans le 1er cas, tu n'auras qu'une date qui apparaitra et qui est déduite par le "SELECT max(...)"

    et dans le 2eme cas tu filtre sur les id et du coup tes critères de date ne fonctionneront pas.

    Essaie le code que je t'ai mis ou alors exprime mieux ton besoin.

  5. #5
    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
    J'ai rajouté quelques dates parce que le pas de test n'était pas suffisant :
    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
    WITH T AS
    (
    select 1 id, 50 val, convert(smalldatetime, '10/10/2008') dt union
    select 1, 34 val, convert(smalldatetime, '09/01/2008') union
    select 1, 18 val, convert(smalldatetime, '08/01/2008') union
    select 2, 23 val, convert(smalldatetime, '10/05/2008') union
    select 2, 45 val, convert(smalldatetime, '07/02/2008') union
    select 2, 15 val, convert(smalldatetime, '07/01/2008') union
    select 3, 23 val, convert(smalldatetime, '10/09/2008')
    ),
     T2 AS
    (
    select T.*, rank() OVER (PARTITION BY T.id ORDER BY T.dt DESC) rk
    from T
    where T.dt <= convert(smalldatetime, '09/01/2008')
    )
    select T2.id, T2.val, T2.dt
    from T2
    where rk = 1

  6. #6
    jnore
    Invité(e)
    Par défaut
    Citation Envoyé par Waldar Voir le message
    J'ai rajouté quelques dates parce que le pas de test n'était pas suffisant :
    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
    WITH T AS
    (
    select 1 id, 50 val, convert(smalldatetime, '10/10/2008') dt union
    select 1, 34 val, convert(smalldatetime, '09/01/2008') union
    select 1, 18 val, convert(smalldatetime, '08/01/2008') union
    select 2, 23 val, convert(smalldatetime, '10/05/2008') union
    select 2, 45 val, convert(smalldatetime, '07/02/2008') union
    select 2, 15 val, convert(smalldatetime, '07/01/2008') union
    select 3, 23 val, convert(smalldatetime, '10/09/2008')
    ),
     T2 AS
    (
    select T.*, rank() OVER (PARTITION BY T.id ORDER BY T.dt DESC) rk
    from T
    where T.dt <= convert(smalldatetime, '09/01/2008')
    )
    select T2.id, T2.val, T2.dt
    from T2
    where rk = 1

    Je ne vois pas trop le rapport avec la discussion, à mon avis tu t'es trompé de post !!

  7. #7
    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
    Hormis le fait que le pas de test est dans le premier bloc WITH, et donc potentiellement superflu pour gudul, je pense que ma requête renvoie le résultat demandé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    id          val         dt
    ----------- ----------- -----------------------
    1           34          2008-09-01 00:00:00
    2           45          2008-07-02 00:00:00
    Ca ne vous rappelle rien ?

  8. #8
    jnore
    Invité(e)
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Hormis le fait que le pas de test est dans le premier bloc WITH, et donc potentiellement superflu pour gudul, je pense que ma requête renvoie le résultat demandé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    id          val         dt
    ----------- ----------- -----------------------
    1           34          2008-09-01 00:00:00
    2           45          2008-07-02 00:00:00
    Ca ne vous rappelle rien ?
    Ca me parait bien compliqué:
    Est-ce que cela ne ferait pas l'affaire?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT id,valeur
    FROM sa_table
    WHERE date BETWEEN 
        (
        SELECT max(date) 
        FROM sa_table 
        WHERE date< '2008-09-10'
        ) 
        AND '2008-09-10'
    Cela est valable dans la mesure où le passage du paramètre peut être renseigné 2 fois (au niveau des deux bornes du between)

  9. #9
    Membre régulier
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    175
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 175
    Points : 106
    Points
    106
    Par défaut
    Je me suis peut être mal exprimer.
    Je prend un autre exemple.
    Imaginons que je suive les prix des légumes de mon supermarché.
    J'enregistre la valeur, la date(sans les heures) pour chaque legumes à chaque changement de prix.

    Je veux pouvoir avoir le prix de l'ensemble de mes légumes à une date donnée.

    Le 1 juillet 2008, les carottes coutaient 3,4€, les haricots 2,5€ ...

    Ce code me conviendrait si je n'avais pas de changement de cout possible plusieurs fois dans la même journée. (mes patates sont à 3€ le matin et 3,4€ l'après midi)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT NomLegume, Cout, DateChgt
    FROM MATABLELegume a
    WHERE a.DateChgt = (SELECT max(b.DateChgt) 
                         FROM MATABLELegume b 
                         WHERE b.DateChgt<= :MaDateParam and a.NomLegume = b.NomLegume)
    On va considérer que l'on enregistre toujours dans l'ordre des dates et que l'on a une colonne IdEnreg qui contient la Id de la séquence.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    IdEnr NomLegume Cout   Date
    1     carottes   3,4  01/06/2008
    2     Patates    2,5  01/06/2008
    3     Salade     1,2  02/06/2008
    4     carottes   3,6  05/06/2008
    5     Salade     1,4  05/06/2008
    6     patates    2,6  08/06/2008
    7     patates    2,8  08/06/2008
    8     carottes   2,8  20/06/2008
    9     salade     1,1  25/06/2008
    10    patates    3,0  30/06/2008
    Si je passe le 20/06/2008 il me faut
    8 carottes 2,8 20/06/2008
    7 patates 2,8 08/06/2008
    5 salade 1,4 05/06/2008

    Jnore, je pense que ta requête va me remonter uniquement l'id /valeur de l'enregistrement le plus proche inférieur de la date et non un enregistrement pour chaque Id(legume)

  10. #10
    Membre à l'essai
    Inscrit en
    Juillet 2003
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 20
    Points : 14
    Points
    14
    Par défaut
    Salut,

    Sans vouloir vous embrouiller plus encore, j'ai l'impression que c'est exactement le meme probleme que celui qui vient d'etre résolu pour moi ici.
    C'est, entre autres, Waldar qui avait trouvé la solution, avec SQL pro (encore merci au passage ).

    Olif.

  11. #11
    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
    Tout à fait Olif, j'ai adapté la syntaxe de ma requête car SQL Server ne connait pas la fonction analytique FIRST_VALUE.

    Gudul, avez-vous essayé ce que je vous ai proposé ?
    La même requête adaptée à votre second exemple (et ce sera la dernière).

    Pas de test :
    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
    WITH T AS
    (  
    SELECT 1 IdEnr, 'carottes' NomLegume, 3.4 Cout,  convert(smalldatetime, '06/01/2008') dt union
    SELECT 2, 'Patates', 2.5,  convert(smalldatetime, '06/01/2008') union
    SELECT 3, 'Salade', 1.2,  convert(smalldatetime, '06/02/2008') union
    SELECT 4, 'carottes', 3.6,  convert(smalldatetime, '06/05/2008') union
    SELECT 5, 'Salade', 1.4,  convert(smalldatetime, '06/05/2008') union
    SELECT 6, 'patates', 2.8,  convert(smalldatetime, '06/08/2008') union
    SELECT 7, 'patates', 2.8,  convert(smalldatetime, '06/08/2008') union
    SELECT 8, 'carottes', 2.8,  convert(smalldatetime, '06/20/2008') union
    SELECT 9, 'salade', 1.1,  convert(smalldatetime, '06/25/2008') union
    SELECT 10, 'patates', 3.0,  convert(smalldatetime, '06/30/2008')
    )
    select * from T
     
     
    IdEnr       NomLegume Cout                                    dt
    ----------- --------- --------------------------------------- -----------------------
    1           carottes  3.4                                     2008-06-01 00:00:00
    2           Patates   2.5                                     2008-06-01 00:00:00
    3           Salade    1.2                                     2008-06-02 00:00:00
    4           carottes  3.6                                     2008-06-05 00:00:00
    5           Salade    1.4                                     2008-06-05 00:00:00
    6           patates   2.8                                     2008-06-08 00:00:00
    7           patates   2.8                                     2008-06-08 00:00:00
    8           carottes  2.8                                     2008-06-20 00:00:00
    9           salade    1.1                                     2008-06-25 00:00:00
    10          patates   3.0                                     2008-06-30 00:00:00
     
    (10 row(s) affected)
    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
    28
    29
    30
    WITH T AS
    (  
    SELECT 1 IdEnr, 'carottes' NomLegume, 3.4 Cout,  convert(smalldatetime, '06/01/2008') dt union
    SELECT 2, 'Patates', 2.5,  convert(smalldatetime, '06/01/2008') union
    SELECT 3, 'Salade', 1.2,  convert(smalldatetime, '06/02/2008') union
    SELECT 4, 'carottes', 3.6,  convert(smalldatetime, '06/05/2008') union
    SELECT 5, 'Salade', 1.4,  convert(smalldatetime, '06/05/2008') union
    SELECT 6, 'patates', 2.8,  convert(smalldatetime, '06/08/2008') union
    SELECT 7, 'patates', 2.8,  convert(smalldatetime, '06/08/2008') union
    SELECT 8, 'carottes', 2.8,  convert(smalldatetime, '06/20/2008') union
    SELECT 9, 'salade', 1.1,  convert(smalldatetime, '06/25/2008') union
    SELECT 10, 'patates', 3.0,  convert(smalldatetime, '06/30/2008')
    ),
     T2 AS
    (
    SELECT T.*, rank() OVER (PARTITION BY T.NomLegume ORDER BY T.dt DESC, IdEnr DESC) rk
    FROM T
    WHERE T.dt <= convert(smalldatetime, '06/20/2008') -- Ici votre paramètre, attention au format 'MM/JJ/AAAA'
    )
    SELECT T2.IdEnr, T2.NomLegume, T2.Cout, T2.dt
    FROM T2
    WHERE rk = 1
     
    IdEnr       NomLegume Cout                                    dt
    ----------- --------- --------------------------------------- -----------------------
    8           carottes  2.8                                     2008-06-20 00:00:00
    7           patates   2.8                                     2008-06-08 00:00:00
    5           Salade    1.4                                     2008-06-05 00:00:00
     
    (3 row(s) affected)

Discussions similaires

  1. [Toutes versions] Sélection sur plus proche valeur de date
    Par dchiche dans le forum Access
    Réponses: 10
    Dernier message: 25/02/2014, 17h59
  2. Date au plus proche
    Par mitchb dans le forum Langage SQL
    Réponses: 1
    Dernier message: 21/07/2008, 11h31
  3. Selectionner la date la plus proche
    Par goodboy dans le forum SQL
    Réponses: 4
    Dernier message: 14/08/2007, 11h36
  4. [DEBUTANT]recherche de date - heure la plus proche
    Par tripper.dim dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 13/06/2007, 12h15
  5. [FireBird] date la plus proche
    Par gudul dans le forum Langage SQL
    Réponses: 1
    Dernier message: 16/05/2006, 09h09

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