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 :

UPDATE premier élement suivant <> zéro


Sujet :

Langage SQL

  1. #1
    Nouveau membre du Club
    Inscrit en
    Mars 2006
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 53
    Points : 30
    Points
    30
    Par défaut UPDATE premier élement suivant <> zéro
    Bonjour,
    je n'arrive pas réaliser une requete de mise a jour. Voici ce que j'ai :
    une seule table avec pour valeur :

    ID Montant
    1 2
    2 2
    3 0
    4 3
    5 0
    6 0
    7 8

    je veux que toute mes montant qui sont égal à zéro prenne la prochaine valeur dans la liste non égale à zéro. et donc arriver à

    ID Montant
    1 2
    2 2
    3 3
    4 3
    5 8
    6 8
    7 8

    et question subsidiaire , pour gérer le cas ou je ne trouve pas de valeur <> 0 dans la suite de ma liste , je prend le dernier montant connu :

    ID Montant
    7 8
    8 10
    9 0
    10 0

    deviendrait :

    ID Montant
    7 8
    8 10
    9 10
    10 10

    (dans l'idéal je voudrais prendre le montant non égale a zero le plus proche de mon ID, mais j'en demande bcp la )

    MErci pour votre aide !

  2. #2
    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
    Quel est votre SGBD ?

  3. #3
    Nouveau membre du Club
    Inscrit en
    Mars 2006
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 53
    Points : 30
    Points
    30
    Par défaut
    SQL SERVER 2012

  4. #4
    Nouveau membre du Club
    Inscrit en
    Mars 2006
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 53
    Points : 30
    Points
    30
    Par défaut
    Je suis sur cette piste... mais dans le flou le plus total
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      UPDATE MATABLE
     
      SET MATABLE.[MONTANT] = (Select top (1)  t2.[MONTANT] )
      FROM MATABLE as t1 , (Select ID , [MONTANT] FROM MATABLE ) as t2
      where t2.ID >  t1.ID and t2.[MONTANT] <> '0.000000'

  5. #5
    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
    Essayez ainsi :
    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
    update matable
       set matable.montant = src.montant_new
      from (select id
                 , case
                     when 0 = montant
                      and 0 = max(montant) over(partition by minid)
                     then max(montant) over(partition by maxid)
                     when 0 = montant
                     then max(montant) over(partition by minid)
                     else montant
                   end as montant_new
              from (select id
                         , min(case when montant > 0 then id end) over(order by id desc) as minid
                         , max(case when montant > 0 then id end) over(order by id  asc) as maxid
                         , montant
                      from matable
                   ) as t
           ) as src
     where matable.id      = src.id
       and matable.montant = 0

  6. #6
    Nouveau membre du Club
    Inscrit en
    Mars 2006
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 53
    Points : 30
    Points
    30
    Par défaut
    cette requete ne passe pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select id
                         , min(case when montant > 0 then id end) over(order by id desc) as minid
                         , max(case when montant > 0 then id end) over(order by id  asc) as maxid
                         , montant
                      from matable
    cela me dit : Syntaxe incorrecte vers 'order'.

  7. #7
    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
    J'ai testé sur un 2014 mais ça devrait fonctionner.
    Vous êtes bien sûr d'être en SQL-Server 2012 ?

  8. #8
    Nouveau membre du Club
    Inscrit en
    Mars 2006
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 53
    Points : 30
    Points
    30
    Par défaut
    Mince, je me suis trompé : j'ai sql 2008...

    Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64)

  9. #9
    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
    Dernière question, vous avez beaucoup de lignes dans votre table ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select count(*), count(case montant when 0 then 1 end)
      from matable
    Parce que je vous ai écrit une belle solution performante, mais si c'est pour 200 lignes je vais faire différemment.

  10. #10
    Nouveau membre du Club
    Inscrit en
    Mars 2006
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 53
    Points : 30
    Points
    30
    Par défaut
    j'ai réussi a faire ceci pour la premiere etape :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    UPDATE MATABLE
      SET Montant  = ( select top (1) T.Montant )
      FROM (SELECT  Montant,ID FROM MATABLE where Montant <> 0) as SRC
      WHERE MATABLE.ID < SRC.ID and  MATABLE.Montant = 0
    cela semble fonctionné, car ID etant la clé primaire , il est trié.

    Mais pour la seconde étape , je voulais faire un second update (je ne maîtrise pas assez les case) dans ce genre , simplement en inversant la condition :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    UPDATE MATABLE
      SET Montant  = ( select top (1) SRC.Montant )
      FROM (SELECT  Montant,ID FROM MATABLE where Montant <> 0) as SRC
      WHERE MATABLE.ID > SRC.ID and  MATABLE.Montant = 0
    mais le top (1) va me chercher la première valeur au lieu de la dernière, et je ne peux pas ordonner SRC (sql server refuse de le faire dans une requête imbriquée)

  11. #11
    Nouveau membre du Club
    Inscrit en
    Mars 2006
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 53
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Dernière question, vous avez beaucoup de lignes dans votre table ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select count(*), count(case montant when 0 then 1 end)
      from matable
    Parce que je vous ai écrit une belle solution performante, mais si c'est pour 200 lignes je vais faire différemment.
    Oui merci, j'avoue qu'elle me dépasse votre requête...
    J'ai plus de 500000 lignes

  12. #12
    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
    Est-ce que ces requêtes fonctionnent ?
    Côté performance je ne vous garantis rien par contre.
    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
    update matable
       set montant = src.montant
      from (select t1.id
                 , t2.montant
                 , row_number() over(partition by t1.id order by t2.id asc) as rn
              from matable as t1
              join matable as t2 on t2.id > t1.id
             where t1.montant = 0
               and t2.montant > 0) as src
     where matable.montant = 0
       and matable.id      = src.id
       and src.rn          = 1
    go
     
    update matable
       set montant = src.montant
      from (select t1.id
                 , t2.montant
                 , row_number() over(partition by t1.id order by t2.id desc) as rn
              from matable as t1
              join matable as t2 on t2.id < t1.id
             where t1.montant = 0
               and t2.montant > 0) as src
     where matable.montant = 0
       and matable.id      = src.id
       and src.rn          = 1
    go

  13. #13
    Nouveau membre du Club
    Inscrit en
    Mars 2006
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 53
    Points : 30
    Points
    30
    Par défaut
    Ca a l'air de marche merci, je pense pouvoir me débrouille maintenant !
    merci

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 27/11/2012, 11h16
  2. Construction ensemble premier et suivant
    Par Alays dans le forum Mathématiques
    Réponses: 0
    Dernier message: 12/05/2012, 15h33
  3. [XL-2007] liste de validation - comment se placer sur le premier élement
    Par vali25 dans le forum Excel
    Réponses: 2
    Dernier message: 07/03/2012, 10h05
  4. Réponses: 4
    Dernier message: 15/05/2010, 16h17
  5. Réponses: 2
    Dernier message: 26/03/2009, 10h21

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