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 :

Max(date) dans select case when


Sujet :

MS SQL Server

  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 93
    Points : 74
    Points
    74
    Par défaut Max(date) dans select case when
    Bonjour ,

    J'essaie de construire une requête qui me retourne le résultat en fonction des cases .
    sauf que mon problème est que mon case me retourne un résultat à chaque clause car il ne pointe pas sur la dernière date d’enregistrement.

    actuellement j'ai ce résultat :
    Date DOS_ID Status_Code
    2012-05-03 456 20
    2012-12-13 456 30,
    2014-05-15 456 50,
    2013-05-21 456 80
    2011-05-23 789 90,
    2012-07-23 789 30,
    2013-11-26 352 80
    2012-12-23 352 90,
    2011-06-09 352 50,
    je souhaite obtenir le derniers enregistrement par statut
    Date DOS_ID Status_Code
    2014-05-15 456 50
    2012-07-23 789 30,
    2013-11-26 352 80,


    est ce que je dois ajouter un :

    1-HAVING pour selectionner les Max(Date)

    ou

    2-ajouter dans mon from un select (max(date) from ma table_1 ) inner join ....

    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
    SELECT DISTINCT max(date),CAS_CODE , STATUS_CODE , "TO"=
     
    CASE	
    	WHEN STATUS_CODE IN  (20,30,50) THEN (SELECT NOM_CREATOR)
    	WHEN STATUS_CODE IN (70,80)THEN (SELECT NOM_MANAGER)
    	WHEN STATUS_CODE IN (90)THEN (SELECT NOM_TEAM)
    	WHEN STATUS_CODE IN (100,10)THEN (SELECT NOM_EMPLOY)
     
     
    END
     
    FROM 
     
    MA_TABLE_1 
    INNER JOIN MA_TABLE_2 ON ID_1 = ID_2
    INNER JOIN MA_TABLE_3 ON ID_3 = ID_4
    INNER JOIN MA_TABLE_4 ON ID_4 = ID_2
     
    LEFT JOIN MA_TABLE_5 ON ID_5 = ID_2
    LEFT JOIN MA_TABLE_6 ON ID_7 = ID_2
     
    WHERE 
     
    DOS_ID IN (352,456,789,...,...)
     
    GROUP BY
     
    NOM_CREATOR
    NOM_MANAGER
    NOM_TEAM
    NOM_EMPLOY
    Je reste dans l'attente d'un retour de votre part concernant la structure de ma requête . est ce que je dois changer de syntaxe (utilisation de case)ou je dois ajouter une sous requête pour limiter le résultat sur les derniers enregistrements.

    merci de laisser des commentaires

  2. #2
    Membre éprouvé
    Avatar de landry161
    Homme Profil pro
    C#,PHP,MySQL,Android...
    Inscrit en
    Juillet 2010
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : C#,PHP,MySQL,Android...

    Informations forums :
    Inscription : Juillet 2010
    Messages : 423
    Points : 1 059
    Points
    1 059
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par varik Voir le message

    je souhaite obtenir le derniers enregistrement par statut
    Date Cas_Code Status_Code
    2014-05-15 456 50
    2012-07-23 789 30,
    2013-11-26 352 80,
    Ce tableau, il est obtenu selon quel critère?

  3. #3
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 93
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par landry161 Voir le message
    Ce tableau, il est obtenu selon quel critère?
    Merci pour la réflexion, j'ai rectifié mon message . il s'agit du Dos_ID au lieu du Cas_code dans le tableau résultat.
    le principe est de partir d'un cas , trouver sa dernière date d'enregistrement et pointer sur son statut pour faire une action différente .
    d'ou ma structure en case . sauf que mon case retourne à chaque clause le résultat par dernière date par statut au lieu de me retourner juste le statut correspondant au dernier enregistrement.

    j’espère avoir apporté un petit éclairage .


  4. #4
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Le sous-select, sous SQL Server 2014 en tout cas, semble une bonne solution.

    En effet, d'après le plan d'exécution, la table n'est lue qu'une seule fois !

    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
    27
    28
    29
    30
    31
    32
    33
     
    drop table test;
    go
     
    create table test
    (
    	dte date not null, 
    	dos_id int not null, 
    	status_code int not null
    );
    go
     
    alter table test
    add constraint uc_date_dos unique (dte, dos_id);
    go
     
    insert into test (dte, dos_id, status_code) values ('2012-05-03', 456, 20);
    insert into test (dte, dos_id, status_code) values ('2012-12-13', 456, 30);
    insert into test (dte, dos_id, status_code) values ('2014-05-15', 456, 50);
    insert into test (dte, dos_id, status_code) values ('2013-05-21', 456, 80);
    insert into test (dte, dos_id, status_code) values ('2011-05-23', 789, 90);
    insert into test (dte, dos_id, status_code) values ('2012-07-23', 789, 30);
    insert into test (dte, dos_id, status_code) values ('2013-11-26', 352, 80);
    insert into test (dte, dos_id, status_code) values ('2012-12-23', 352, 90);
    insert into test (dte, dos_id, status_code) values ('2011-06-09', 352, 50);
     
    select t2.dte, t2.dos_id, t2.status_code
    from test t2
    inner join (
    	select max(t1.dte) dte, t1.dos_id
    	from test t1
    	group by dos_id
    ) tmp on tmp.dte = t2.dte and tmp.dos_id = t2.dos_id;

    http://prntscr.com/4731wd
    On ne jouit bien que de ce qu’on partage.

  5. #5
    Membre éprouvé
    Avatar de landry161
    Homme Profil pro
    C#,PHP,MySQL,Android...
    Inscrit en
    Juillet 2010
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : C#,PHP,MySQL,Android...

    Informations forums :
    Inscription : Juillet 2010
    Messages : 423
    Points : 1 059
    Points
    1 059
    Billets dans le blog
    1
    Par défaut Proposition
    jE prendrai l'exemple de la table créee par StringBuilder
    Citation Envoyé par StringBuilder Voir le message

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    drop table test;
    go
     
    create table test
    (
    	dte date, 
    	dos_id int, 
    	status_code int
    );
    go
    J'ai procédé d'une autre manière,tout compte fait une solution de plus c'est pas mauvais.
    Alors la voici.

    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
     
    --C'est un code Transact SQL
    Declare 
    --Je déclare deux variables de type entier qui contiendront les valeur minimales et maximales de stauts_code
    @minimum int,@maximum int 
     
    set @maximum = (select MAX(status_code ) from La_Table)
    set @minimum=(select MIN(status_code ) from La_Table)
     
    WHILE(@minimum<>@maximum) 
    BEGIN
           INSERT INTO test(dte,dos_id,status_code) SELECT  top 1 dte,dos_id,status_code FROM La_Table
           WHERE(status_code=@minimum) 
           ORDER BY dte DESC;
           --Incrémentation
           SET @minimum=@minimum+1
    END;

  6. #6
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 93
    Points : 74
    Points
    74
    Par défaut
    Bonjour ,

    Merci de vos réponses StrringBuilder et landry161.
    Pour commencer, je rappelle les régles :

    1-Traiter des cas_code en fonction de leur statuts_code.
    2-Pour cela, il faut pointer sur la dernière date d'enregistrement du cas_code pour retrouver son statuts _code.
    3-Le cas_code et et le statut_code deux champs de deux différentes tables.

    Avant d'aller plus loin, j'aimerai savoir si je peux garder mon case ou si une structure avec des blocs Exists serait envisageable .

    Donc pour l'instant le plus proche de mon cas reste la solution proposé par StrringBuilder . Toutefois je commence à me pencher plus le code de landry161 afin de passer par des variables pour faire des comparaison sur les dates .

    à condition que cette solution offre des temps d’exécution court .

    En conclusion ,la syntaxe de StrringBuilder reste à adapter à mon contexte puisque je dispose de jointure sur beaucoup de table.d'ailleurs je me suis pausé la question si on pouvait faire la même chose dans le where et indiquer que l'on souhaite récupérer les max(date) dans le résultat.

  7. #7
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Je ne vois pas ce qui t'empêche de faire des jointures dans ma requête (soit dans le sous-select, soit sur le résultat final, sous forme d'un sous-select).

    Pour la solution de landry, j'avoue que j'ai pas du tout compris ce que sa solution est censée faire. J'ai du zapper un bout de l'énoncé, car je vois pas le rapport.
    On ne jouit bien que de ce qu’on partage.

  8. #8
    Membre éprouvé
    Avatar de landry161
    Homme Profil pro
    C#,PHP,MySQL,Android...
    Inscrit en
    Juillet 2010
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : C#,PHP,MySQL,Android...

    Informations forums :
    Inscription : Juillet 2010
    Messages : 423
    Points : 1 059
    Points
    1 059
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par varik Voir le message

    je souhaite obtenir le derniers enregistrement par statut
    Date DOS_ID Status_Code
    2014-05-15 456 50
    2012-07-23 789 30,
    2013-11-26 352 80,
    Le script que j'ai écrit permet d'afficher le dernier enregistrement par statut.Sachant que le statut est un entier,j'utilise deux variables qui sont censées contenir les maximums et minimums des statuts c'est pour quoi vous voyez
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    DECLARE 
    @minimum int,@maximum int 
    set @minimum=(SELECT MIN(Status_Code) FROM "La_Table")
    set @maximum=(SELECT MAX(Status_Code) FROM "La_Table")
    Le reste se déroule dans une boucle WHILE qui fait la comparaison du status_code et la valeur @minimum et en cas d'égalité on extrait la première ligne du select en tenant compte de la date et on procède à l'insertion dans la table test.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    WHILE(@minimum<>@maximum) 
    BEGIN
           INSERT INTO test(dte,dos_id,status_code) SELECT  top 1 dte,dos_id,status_code FROM La_Table
           WHERE(status_code=@minimum) 
           ORDER BY dte DESC;
           --Incrémentation
           SET @minimum=@minimum+1
    END;
    C'est pas si compliqué que ça
    Tout compte fait si t'as eu une solution à ton problème c'est l'essentiel

  9. #9
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 93
    Points : 74
    Points
    74
    Par défaut
    StrinBuilder, je t'avoue que je n'ai pas d'autre choix que d'opter pour ta solution et ta syntaxe . J'essaie juste de trouver une alternative et éviter les cases (j'aime bien avoir le choix de solution pour un problème).

    pour la proposition de landry161, j'ai précisé que j'allais faire des comparaison sur les dates pour prendre la date max par cas_code et voir d'autre critère . d'ailleurs j'en profite pour te dire qu'une incrémentation avec un pas de 1 va multiplier le temps d’exécution par 10 facilement et que mon problème est un soucis de date et non de cas_code.

    Donc je vais garder la syntaxe en case pour l'instant et essayer de partir plus loin avec les sous-select .
    Je me pencherai une peu plutard sur les temps d’exécution.

    Merci à vous deux , ce post sera marqué en résolu mais vous pouvez laissez d'autre commentaires.

  10. #10
    Membre éprouvé
    Avatar de landry161
    Homme Profil pro
    C#,PHP,MySQL,Android...
    Inscrit en
    Juillet 2010
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : C#,PHP,MySQL,Android...

    Informations forums :
    Inscription : Juillet 2010
    Messages : 423
    Points : 1 059
    Points
    1 059
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par varik Voir le message
    Merci à vous deux , ce post sera marqué en résolu mais vous pouvez laissez d'autre commentaires.
    Non mais pas de quoi c est un forum donc quand il y a une préoccupation chacun apporte sa modeste contribution

  11. #11
    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
    et une fonction fenêtrée avec un row_number() over ( partition by date order by date ) te permettrait d'identifier la première ligne de chaque date.. et éviterait cette horreur de boucle/curseur contre performant.
    Rejoignez la communauté du chat et partagez vos connaissances ou vos questions avec nous

    Mon Tutoriel pour apprendre les Agregations
    Consultez mon Blog SQL destiné aux débutants

    Pensez à FAQ SQL Server Ainsi qu'aux Cours et Tuto SQL Server

Discussions similaires

  1. Mettre select max(date) dans un paramètre
    Par info dans le forum Développement de jobs
    Réponses: 0
    Dernier message: 25/06/2008, 15h41
  2. Access et SELECT CASE WHEN dans requetes
    Par Orion01 dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 06/12/2007, 11h24
  3. [Dates] répétition de dates dans select
    Par godjojo dans le forum Langage
    Réponses: 8
    Dernier message: 29/10/2007, 08h34
  4. Réponses: 7
    Dernier message: 29/05/2007, 10h21
  5. Equivalent "Select Case when then else end" sur Paradoxe
    Par Seuh.m dans le forum Bases de données
    Réponses: 4
    Dernier message: 29/06/2006, 08h23

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