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() et inner join


Sujet :

MS SQL Server

  1. #1
    Membre éclairé Avatar de laloune
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2005
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2005
    Messages : 487
    Par défaut Max() et inner join
    Bonjour à tous,

    j'ai une petite question concernant la fonction max(). Voici un extrait de ma table MIETVERTRAEGE:

    VERTRAGSNUMMER | MVANUMMER | KFZExchangeNo | BASENR
    100493 | 10054 | 1 | 100493
    200000007 | 10002 | 2 | 100493
    200000008 | 10054 | 3 | 100493
    200000016 | 10010 | 4 | 100493

    je cherche à récupérer juste le MVANUMMER de la dernière ligne (10010), c'est à dire celle du maximum de KFZExchangeNo

    lorsque je fais ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    select
    MV.VERTRAGSNUMMER,
    MV.MVANUMMER,
    MAX(MV.KFZExchangeNo)
    FROM MIETVERTRAEGE MV
    WHERE MV.KFZChangeGroupID=8
    GROUP BY MV.VERTRAGSNUMMER, MV.MVANUMMER
    il me renvoie toutes les 4 lignes :-(

    une idée ?

    D'avance merci !

  2. #2
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2008
    Messages
    699
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Boutique - Magasin

    Informations forums :
    Inscription : Octobre 2008
    Messages : 699
    Par défaut
    regarder comment fonctionne les INNER APPLY et les OUTER APPLY moi j'utilise ça quand je dois le faire

    sinon tu as aussi les requêtes imbriquées

  3. #3
    Membre Expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT
    MV.VERTRAGSNUMMER,
    MV.MVANUMMER,
    MAX(MV.KFZExchangeNo) OVER(PARTITION BY 0)
    FROM MIETVERTRAEGE MV
    WHERE MV.KFZChangeGroupID=8
    GROUP BY MV.VERTRAGSNUMMER, MV.MVANUMMER

  4. #4
    Membre éclairé Avatar de laloune
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2005
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2005
    Messages : 487
    Par défaut
    Bonjour à vous deux,

    @Donpi: merci, je vais regarder ca
    @iberserk : il me dit que MIETVERTRAEGE.KFZExchangeNo doit être inclus dans la clause GROUP BY (si j'enlève le OVER(PARTITION BY 0) pas d'erreur, il me renvoie les 4 lignes)

    merci !

  5. #5
    Membre Expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Par défaut
    Pardon je n'ai pas enlevé votre GROUP BY...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT DISTINCT 
    MV.VERTRAGSNUMMER,
    MV.MVANUMMER,
    MAX(MV.KFZExchangeNo) OVER(PARTITION BY 0)
    FROM MIETVERTRAEGE MV
    WHERE MV.KFZChangeGroupID=8

  6. #6
    Membre éclairé Avatar de laloune
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2005
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2005
    Messages : 487
    Par défaut
    euh pardon mais je ne comprends pas, est-ce que votre requête doit renvoyer seulement la ligne :
    200000016 10010

    ?

    car il me renvoie :
    VERTRAGSNUMMER MVANUMMER 3 N/A
    100493 10054 4
    200000007 10002 4
    200000008 10054 4
    200000016 10010 4

  7. #7
    Membre Expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Par défaut
    Je ne comprends pas ce que vous voulez:
    Postez le résultat que vous attendez...

  8. #8
    Membre éclairé Avatar de laloune
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2005
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2005
    Messages : 487
    Par défaut
    Le résultat que j'essaie d'atteindre est:

    VERTRAGSNUMMER | MVANUMMER | 3 N/A
    200000016 | 10010 | 4

  9. #9
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    Quelque chose de ce genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT VERTRAGSNUMMER, MVANUMMER, KFZExchangeNo
    FROM (
    SELECT
    MV.VERTRAGSNUMMER,
    MV.MVANUMMER,
    MV.KFZExchangeNo,
    ROW_NUMBER() OVER(ORDER BY MV.KFZExchangeNo DESC) AS rang
    FROM MIETVERTRAEGE MV
    WHERE MV.KFZChangeGroupID=8
    ) t
    WHERE t.rang = 1

  10. #10
    Expert confirmé
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Par défaut
    ... ou éventuellement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT *
    FROM MIETVERTRAEGE
    WHERE KFZExchangeNo = (SELECT MAX(KFZExchangeNo) FROM MIETVERTRAEGE WHERE KFZChangeGroupID=8)
     AND MV.KFZChangeGroupID=8
    Mais tu ne pourrais pas passer par les agrégats comme tu essaies de faire.
    Tu vas créer des groupes qui rassemblent VERTRAGSNUMMER, MVANUMMER. Hors ceci sont distincts sur les lignes concernées. C'est la raison pour laquelle tu auras tjrs 4 lignes ici.

    ++

  11. #11
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 243
    Billets dans le blog
    16
    Par défaut
    Une variante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    WITH T (KFZExchangeNoMax)
    AS
    (
        SELECT MAX(KFZExchangeNo)
        FROM   MIETVERTRAEGE
        WHERE  KFZChangeGroupID = 8
    )
    SELECT M.* 
    FROM   T JOIN MIETVERTRAEGE AS M ON KFZExchangeNoMax = M.KFZExchangeNo
    WHERE  KFZChangeGroupID = 8 ;

  12. #12
    Membre éclairé Avatar de laloune
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2005
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2005
    Messages : 487
    Par défaut
    Citation Envoyé par mikedavem Voir le message

    Mais tu ne pourrais pas passer par les agrégats comme tu essaies de faire.
    Tu vas créer des groupes qui rassemblent VERTRAGSNUMMER, MVANUMMER. Hors ceci sont distincts sur les lignes concernées. C'est la raison pour laquelle tu auras tjrs 4 lignes ici.

    ++
    c'est absolument corrects, c'est pourtant ce que j'essaie de faire (en fait le KFZChangeGroupID = 8 était juste un exemple pour faire mes tests...)

    je vais essayer de trouver une solution.

    merci à tous pour votre aide,

  13. #13
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 243
    Billets dans le blog
    16
    Par défaut
    Bonsoir laloune,


    En quoi la solution de mikedavem (et la mienne) ne répondent pas à votre besoin ?

  14. #14
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 243
    Billets dans le blog
    16
    Par défaut
    Préférez-vous utiliser une vue ?


    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CREATE VIEW VUE_MAX (KFZExchangeNoMax)
    AS 
        SELECT MAX(KFZExchangeNo)
        FROM   MIETVERTRAEGE
        WHERE  KFZChangeGroupID = 8 ;

    Puis :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT M.*
    FROM   VUE_MAX AS T JOIN MIETVERTRAEGE AS M ON T.KFZExchangeNoMax = M.KFZExchangeNo ;

  15. #15
    Membre éclairé Avatar de laloune
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2005
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2005
    Messages : 487
    Par défaut
    Bonjour,

    en fait je me suis rendu compte que mon problème est un peu plus compliqué:

    - d'une part j'ai filtré sur KFZChangeGroupID = 8 pour restreindre mon dataset pour pouvoir faire des tests, mais ce filtre est amené à disparaitre car je dois faire le même traitement sur toute la table

    - en fait l'idée c'est que ma table MIETVERTRAEGE contient des informations relatives à des contrats de location de voiture.

    Dans cette table j'ai une colonne BASENUMMER qui est le numéro de base, auxquels sont liés des modifications de contrats (une ligne par modification)

    Dans notre exemple, le basenummer est 100493, et les numéros de contrats sont 100493, 200000007, 200000008, 200000016. On identifie la modification la plus récente grace à la colonne KFZExchangeNo (qui peut prendre les valeurs null, c'est à dire pas de modification, à n)

    l'idée est de récupérer la ligne ayant la valeur maximale de KFZExchangeNo (afin d'avoir la modification la plus récente)

    je ne sais pas trop si c'est clair, et si c'est possible de faire ca avec sql server

    merci pour votre aide en tous cas !

  16. #16
    Membre Expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Par défaut
    On reprend à zéro: commencez par respecter la charte du forum!
    Ainsi:
    • Postez les DLL (code de création) de votre table
    • Un petit jeu de donnée,
    • Le résultat escompté pour ce jeu de donnée.

    Cela évitera que l'on perde inutilement notre temps!

    Merci pour nous...

  17. #17
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    Si j'ai bien compris il faut sélectionner le max de KFZExchangeNo pour chaque BaseNR. Il suffit dans la requête que j'ai proposée de changer la clause partition by de la fonction de fenêtrage:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SELECT VERTRAGSNUMMER, MVANUMMER, BASENR , KFZExchangeNo
    FROM (
    SELECT
    MV.VERTRAGSNUMMER,
    MV.MVANUMMER,
    MV.KFZExchangeNo
    MV.BASENR,
    ROW_NUMBER() OVER(PARTITION BY BASENR ORDER BY MV.KFZExchangeNo DESC) AS rang
    FROM MIETVERTRAEGE MV
    WHERE MV.KFZChangeGroupID=8
    ) t
    WHERE t.rang = 1
    Et si je n'ai pas bien compris, alors cf post d'iberserk ci-dessus !

  18. #18
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 243
    Billets dans le blog
    16
    Par défaut
    Avec les variantes :

    1) Utilisation d'une vue :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE VIEW VUE_MAX (BASENR, KFZExchangeNoMax)
    AS 
        SELECT BASENR, MAX(KFZExchangeNo)
        FROM   MIETVERTRAEGE
        GROUP BY BASENR ;
    ...
     
    SELECT M.*
    FROM   VUE_MAX AS T JOIN MIETVERTRAEGE AS M 
                                           ON  T.BASENR = M.BASENR
                                           AND T.KFZExchangeNoMax = M.KFZExchangeNo ;


    2) Utilisation d'une CTE (Common table expression) :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    WITH T (BASENR, KFZExchangeNoMax)
    AS
    (
        SELECT BASENR, MAX(KFZExchangeNo)
        FROM   MIETVERTRAEGE
        GROUP BY BASENR
    )
    SELECT M.* 
    FROM   T JOIN MIETVERTRAEGE AS M 
                                ON  T.BASENR = M.BASENR
                                AND T.KFZExchangeNoMax = M.KFZExchangeNo ;

  19. #19
    Membre éclairé Avatar de laloune
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2005
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2005
    Messages : 487
    Par défaut
    Citation Envoyé par Rei Ichido Voir le message
    Si j'ai bien compris il faut sélectionner le max de KFZExchangeNo pour chaque BaseNR.
    c'est exactement ca.

    et la requête proposée fonctionne tout à fait.

    merci à tous pour votre aide et votre patience. j'observerai la procédure décrite par iberserk la prochaine fois.

    Bonne soirée!

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

Discussions similaires

  1. Performance versus INNER JOIN et MAX
    Par Griswold dans le forum Développement
    Réponses: 1
    Dernier message: 27/08/2010, 19h41
  2. Mysql Inner join
    Par ..:: Atchoum ::.. dans le forum Requêtes
    Réponses: 3
    Dernier message: 25/10/2007, 12h21
  3. [ requeste sql ]INNER JOIN / OUTER JOIN
    Par hocinema dans le forum Langage SQL
    Réponses: 2
    Dernier message: 12/04/2004, 21h28
  4. Erreur lors d'une requete INNER JOIN
    Par k-lendos dans le forum Langage SQL
    Réponses: 2
    Dernier message: 17/03/2004, 15h09
  5. Inner Join & Select
    Par bakaneko dans le forum Langage SQL
    Réponses: 7
    Dernier message: 10/02/2004, 10h48

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