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 :

UPDATE Set Max et Jointures [2008R2]


Sujet :

Développement SQL Server

  1. #1
    Membre habitué
    Inscrit en
    Octobre 2006
    Messages
    316
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 316
    Points : 146
    Points
    146
    Par défaut UPDATE Set Max et Jointures
    Bonjour,

    Je cale sur une requête..
    Mon objectif est de mettre à jour la date MAX de "date_Appel" au travers de ces jointures..
    Mais apparement, SQL n'aime pas du tout le MAX sur un "SET"

    Merci pour votre aide les amis..!

    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
    declare @fait_le as datetime
    set @fait_le = (select Date_precedente from dbo.GMAO_gamme
    				where gamme = '39010'
    				)
    -------------
    Update Gmao_DEMANDE
    Set MAX(GMAO_Demande.Date_appel) = @fait_le
     
    FROM GMAO_DEMANDE
     
    INNER JOIN GMAO_OI
    ON GMAO_OI.id_demande = GMAO_Demande.ID
     
    LEFT OUTER JOIN GMAO_Prevoir
    ON GMAO_OI.Id = GMAO_Prevoir.id_oi 
     
    WHERE (GMAO_Demande.ID_Intervention = '1')
    	AND (GMAO_Prevoir.gamme IS NOT NULL)
     
    GROUP BY GMAO_Prevoir.gamme

  2. #2
    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 guilld Voir le message
    Mais apparement, SQL n'aime pas du tout le MAX sur un "SET"

    En effet, car il ne sait pas ce qu'il doit faire :
    Que devrait-il faire si plusieurs lignes ont le même max (ex aequo)

    Par ailleurs, je ne comprend pas bien votre requête. Pourquoi une jointure externe, alors qu'ensuite dans le WHERE vous filtrer sur la colonne non NULL pour cette table ?

    A première vue, je dirai que vous pourriez passer par une sous requête dans une clause NOT EXISTS, pour ne mettre à jour que les lignes pour lesquelles il n'y a pas de [date_appel] supérieure, ou utiliser une fonction de fenêtrage dans une CTE pour arriver à un résultat similaire.
    Mais difficile d'en dire plus sans la structure des tables et une description plus claire du besoin.

  3. #3
    Membre habitué
    Inscrit en
    Octobre 2006
    Messages
    316
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 316
    Points : 146
    Points
    146
    Par défaut
    alors pour être plus clair, voici quelques détails du besoin..

    J'ai 4 tables :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    select gamme, machine, date_precedente from gmao_gamme
    select id_demande from gmao_oi
    select id_oi, gamme from gmao_prevoir
    select id, date_appel, id_materiel from gmao_demande
    gmao_gamme.gamme = gmao_prevoir.gamme
    gmao_oi.id_demande = gmao_prevoir.id_oi
    gmao_demande.date_appel = gmao.date_precedente (objectif à atteindre)

    L'ojectif étant de recopier les dates de "gmao.date_precedente" dans "Gmao_demande"
    Il se trouve que les dates de "gmao.date_precedente" sont les plus à jour.

    Le problème est qu'il y a un historique dans la table "Gmao_demande" qui ne doit être écrasé.
    Et mon but est de mettre à jour le dernier enregistrement de chaque "gmao_demande.date_appel" avec "gmao.date_precedente"

    Je vous donne ma dernière tentative désespérée sachant que ce code sera à exécuter qu'une seule fois (histoire de faire une mise à jour)

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
     
    create table #T
    (Gamme varchar(10), id_materiel varchar(10), date_appel datetime, fait_le datetime)
     
    insert into #T
     
    SELECT GMAO_Prevoir.gamme, gmao_demande.id_materiel
    		, CONVERT(varchar(12), MAX(GMAO_Demande.Date_appel), 103) AS date_appel
    		 ,gmao_gamme.date_precedente as Faite_le
    FROM GMAO_DEMANDE 
     
    INNER JOIN GMAO_OI
    ON GMAO_OI.id_demande = GMAO_Demande.ID
     
    LEFT OUTER JOIN GMAO_Prevoir
    ON GMAO_OI.Id = GMAO_Prevoir.id_oi 
     
    inner join gmao_gamme
    on gmao_prevoir.gamme = Gmao_gamme.gamme
    and gmao_demande.id_materiel = gmao_gamme.machine
     
    WHERE (GMAO_Demande.ID_Intervention = '1')
    	AND (GMAO_Prevoir.gamme IS NOT NULL)
     
    GROUP BY GMAO_Prevoir.gamme, gmao_demande.id_materiel,gmao_gamme.date_precedente
    order by gamme
     
    -------------------------
    Create table #r
    (Gamme varchar(10), id_materiel varchar(10),date_appel datetime, faite_le datetime, Id varchar(10))
     
    insert into #r
     
    Select v.Gamme, #t.id_materiel,v.date_appel,#t.fait_le, v.ID
    		From (SELECT GMAO_Prevoir.gamme
     
    					, CONVERT(varchar(12), MAX(GMAO_Demande.Date_appel), 103) AS date_appel
    					, max(GMAO_Demande.ID) as ID
     
    					FROM GMAO_DEMANDE 
     
    					INNER JOIN GMAO_OI
    					ON GMAO_OI.id_demande = GMAO_Demande.ID
     
    					LEFT OUTER JOIN GMAO_Prevoir
    					ON GMAO_OI.Id = GMAO_Prevoir.id_oi 
     
    					WHERE (GMAO_Demande.ID_Intervention = '1')
    						AND (GMAO_Prevoir.gamme IS NOT NULL)
     
    					GROUP BY GMAO_Prevoir.gamme
    				) as v
     
    inner join #t
    on #t.gamme = v.gamme
    and #t.date_appel = v.date_appel
     
     
     
    -----------------------------------
    DECLARE @Gamme varchar(10), @id_materiel varchar(10), @fait_le datetime, @id varchar(10)
     
    DECLARE Up_gmao CURSOR FOR
     
    	select Gamme, id_materiel, @fait_le, id
    	from #r
     
     
    OPEN Up_gmao
     
    FETCH NEXT FROM Up_gmao
    INTO @gamme, @id_materiel, @fait_le, @id
     
    WHILE @@FETCH_STATUS = 0
    BEGIN
     
    		update gmao_demande
    		set Date_appel = @fait_le
     
    		From gmao_demande
     
    		inner join #r
    		on gmao_demande.id = @id
    		and gmao_demande.id_materiel = @id_materiel
     
     
       FETCH NEXT FROM Up_gmao
       INTO @gamme, @id_materiel, @fait_le, @id
    END
     
     
    CLOSE Up_gmao
    DEALLOCATE Up_gmao
    ----
    select * from #r
     
    Drop table #t, #r

  4. #4
    Membre habitué
    Inscrit en
    Octobre 2006
    Messages
    316
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 316
    Points : 146
    Points
    146
    Par défaut
    Bon...

    Voici le code qui l'a permis de faire le job. Même si c'est pas beau ni optimisé , je rappelle que c'est du jetable.
    Ma base est mise à jour. Merci à ceux qui ont tenté de m'aider.

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
     
    create table #T
    (Gamme varchar(10), id_materiel varchar(10), date_appel datetime, fait_le datetime)
     
    insert into #T
     
    SELECT GMAO_Prevoir.gamme, gmao_demande.id_materiel
    		, CONVERT(varchar(12), MAX(GMAO_Demande.Date_appel), 103) AS date_appel
    		 ,gmao_gamme.date_precedente as Faite_le
    FROM GMAO_DEMANDE 
     
    INNER JOIN GMAO_OI
    ON GMAO_OI.id_demande = GMAO_Demande.ID
     
    LEFT OUTER JOIN GMAO_Prevoir
    ON GMAO_OI.Id = GMAO_Prevoir.id_oi 
     
    inner join gmao_gamme
    on gmao_prevoir.gamme = Gmao_gamme.gamme
    and gmao_demande.id_materiel = gmao_gamme.machine
     
    WHERE (GMAO_Demande.ID_Intervention = '1')
    	AND (GMAO_Prevoir.gamme IS NOT NULL)
     
    GROUP BY GMAO_Prevoir.gamme, gmao_demande.id_materiel,gmao_gamme.date_precedente
    order by gamme
     
    -------------------------
    Create table #r
    (Gamme varchar(10), id_materiel varchar(10),date_appel datetime, faite_le datetime, Id varchar(10))
     
    insert into #r
     
    Select v.Gamme, #t.id_materiel,v.date_appel,#t.fait_le, v.ID
    		From (SELECT GMAO_Prevoir.gamme
     
    					, CONVERT(varchar(12), MAX(GMAO_Demande.Date_appel), 103) AS date_appel
    					, max(GMAO_Demande.ID) as ID
     
    					FROM GMAO_DEMANDE 
     
    					INNER JOIN GMAO_OI
    					ON GMAO_OI.id_demande = GMAO_Demande.ID
     
    					LEFT OUTER JOIN GMAO_Prevoir
    					ON GMAO_OI.Id = GMAO_Prevoir.id_oi 
     
    					WHERE (GMAO_Demande.ID_Intervention = '1')
    						AND (GMAO_Prevoir.gamme IS NOT NULL)
     
    					GROUP BY GMAO_Prevoir.gamme
    				) as v
     
    inner join #t
    on #t.gamme = v.gamme
    and #t.date_appel = v.date_appel
     
     
     
    -----------------------------------
    DECLARE  @fait_le datetime, @id varchar(10)
     
    DECLARE Up_gmao CURSOR FOR
     
    	select fait_le, id
    	from #r
     
     
    OPEN Up_gmao
     
    FETCH NEXT FROM Up_gmao
    INTO @fait_le, @id
     
    WHILE @@FETCH_STATUS = 0
    BEGIN
     
    		update gmao_demande
    		set Date_appel = @fait_le
     
    		where gmao_demande.id = @id
     
     
       FETCH NEXT FROM Up_gmao
       INTO	@fait_le, @id
    END
     
     
    CLOSE Up_gmao
    DEALLOCATE Up_gmao
    ----
    Drop table #t, #r
    --------

  5. #5
    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
    Je pense que ceci aurait fait l'affaire également, a confirmer (et sans doute adapter un peu, mais le principe y est) en fonction de votre modèle qu'on ne connait toujours pas :

    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
     
    WITH CTE AS (
    	SELECT 
    			GMAO_Demande.Date_appel AS X
    			,RANK() OVER (PARTITION BY GMAO_Prevoir.gamme ORDER BY GMAO_Demande.Date_appel DESC) AS Rang
    	FROM Gmao_DEMANDE
    	INNER JOIN GMAO_OI
    		ON GMAO_OI.id_demande = GMAO_Demande.ID
    	INNER JOIN GMAO_Prevoir
    		ON GMAO_OI.Id = GMAO_Prevoir.id_oi 
    	WHERE 
    			GMAO_Demande.ID_Intervention = '1'
    		AND GMAO_Prevoir.gamme IS NOT NULL
    )
    UPDATE CTE 
    	SET  X = (SELECT Date_precedente FROM dbo.GMAO_gamme WHERE gamme = '39010')
    WHERE Rang = 1

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

Discussions similaires

  1. Requete update avec sous requete et max en jointure
    Par youyoupapayou dans le forum Langage SQL
    Réponses: 6
    Dernier message: 27/08/2009, 16h19
  2. UPDATE * SET php/mysql
    Par Invité dans le forum Requêtes
    Réponses: 13
    Dernier message: 28/03/2006, 11h47
  3. [INTERBASE][UPDATE SET WHERE] problème de requete
    Par exclusif dans le forum Langage SQL
    Réponses: 3
    Dernier message: 06/03/2006, 21h10
  4. Réponses: 2
    Dernier message: 02/12/2005, 17h40
  5. Update dans SYBASE avec jointure sur 2 colonnes
    Par metheorn dans le forum Sybase
    Réponses: 2
    Dernier message: 24/06/2005, 16h51

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