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 :

Requête SQL avec "numéro de séquence"


Sujet :

Développement SQL Server

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    octobre 2003
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Associations - ONG

    Informations forums :
    Inscription : octobre 2003
    Messages : 87
    Points : 90
    Points
    90
    Par défaut Requête SQL avec "numéro de séquence"
    Bonjour,

    Je n'arrive pas à réaliser une requête qui, à mon avis, ne devrait pas être compliquée. Seulement, je bloque.

    Je dispose de la table "MATABLE" suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     ID  Diplome   Specialite   Date
    ----------------------------------
     2  Bac          NULL        1990
     3  BAC          NULL        1992
     4  LICENCE      GEO         1995
     4  MAITRISE     GEO         1996
    J'aimerais obtenir le résultat suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     ID  Diplome   Specialite   Date       Sequence
    --------------------------------------------------
     2  Bac          NULL        1990           1
     3  BAC          NULL        1992           1
     4  LICENCE      GEO         1995           1
     4  MAITRISE     GEO         1996           2
    Où Sequence (le terme est peut-être mal choisi) donne le numéro et l'ordre des diplômes obtenus.

    L'ID 2 n'a qu'un diplôme de renseigné => Sequence = 1
    L'ID 3 n'a qu'un diplôme de renseigné => Sequence = 1
    L'ID 4 a deux diplômes de renseigné => Sequence = 1 pour le plus ancien (Date = 1995) et 2 pour le deuxième (Date 1996). Et ainsi de suite.

    Je ne vois pas comment construire cette requête. J'imagine que c'est faisable et c'est surement tout bête.

    Merci donc d'avance de vôtre aide.

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    mai 2002
    Messages
    20 958
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 20 958
    Points : 49 766
    Points
    49 766
    Billets dans le blog
    1
    Par défaut
    ROW_NUMBER() ou RANK() permettent de faire ceci. La syntaxe à adopter est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT ID, Diplome, Specialite, Date, 
           ROW_NUMBER() OVER(PARTITION BY ID ORDER BY DATE) AS Sequence
    FROM   MaTable
    Ceci fait partie du SQL de la norme SQL:2003 (fonctions de fenêtrage).

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    octobre 2003
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Associations - ONG

    Informations forums :
    Inscription : octobre 2003
    Messages : 87
    Points : 90
    Points
    90
    Par défaut
    Bonjour,

    Merci de la réponse.

    Malheureusement, ça ne fonctionne pas que cela soit avec ROW_NUMBER ou RANK.
    Je tiens à préciser mon environnement : la base est sur SQL SERVER 2000. Ce qui, au vu de la date, doit être une bonne explication de l'erreur rencontrée.

    Peut-on à votre avis contourner le problème ?

    Messages d'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    'ROW_NUMBER' n'est pas un nom de fonction reconnu.
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    'RANK' n'est pas un nom de fonction reconnu.

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    mai 2002
    Messages
    20 958
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 20 958
    Points : 49 766
    Points
    49 766
    Billets dans le blog
    1
    Par défaut
    Effectivement ces fonctions ne sont disponible qu'à partir de la version 2005. Une bonne raison pour changer de version, d'autant plus que le support MS pour la v 2000 va s'arrêter en 2010 ! ;-)
    Bon, trêve de plaisanterie.
    Vous pouvez cependant vous en tirer en effectuant une non équi auto jointure avec comptage.
    N'ayant pas le temps de vous montrer cela (je donne une formation en ce moment même) j'espère que vous trouverez la solution par vous même.. Le principe étant dit voici une ébauche de la requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT T1.A, T1.B, T1.C, COUNT(*)
    FROM   Table1 AS T1
              INNER JOIN Table2 AS T2
                    ON T1.A = T2.A
                        AND T1.B >= T2.B
    GROUP  BY T1.A, T1.B, T1.C
    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    octobre 2003
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Associations - ONG

    Informations forums :
    Inscription : octobre 2003
    Messages : 87
    Points : 90
    Points
    90
    Par défaut
    Merci,

    Si j'ai bien compris, les alias de table concernent la même table de départ.
    Si c'est bien cela, la requête que vous proposez n'est pas correcte ? Il faudrait écrire Table1 au lieu du Table2 proposé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT T1.A, T1.B, T1.C, COUNT(*)
    FROM   Table1 AS T1
              INNER JOIN Table1 AS T2
                    ON T1.A = T2.A
                        AND T1.B >= T2.B
    GROUP  BY T1.A, T1.B, T1.C
    Mais je me trompe peut-être et puis, comme vous l'avez dit, vous êtes en formation. C'est déjà assez sympa de me répondre.
    --

    Bon, j'ai fait le test avec vos 2 solutions. Eh oui, pour votre première proposition, j'ai lié la base SQL SERVER 2000 à ma base locale qui est en SQL SERVER EXPRESS 2005.
    Ainsi, j'ai pu lancer la requête contenant la fonction ROW_NUMBER(). ça marche et la requête est finalement assez simple.

    Par acquis de conscience, j'ai construit une requête sur le serveur SQL S2000. J'ai suivi votre conseil sur la version avec equi-auto-jointure. Mais comme l'exemple que je fournissais (MaTable) provenait d'une requête avec jointure, j'ai préféré ne pas ma requête initiale mais créer une table temporaire à partir d'elle, sur laquelle j'exécute la requête selon vos recommandations. Et ça fonctionne.

    #Diplome est ma table temporaire.

    Donc, la requète est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT COUNT(*) AS Sequence, T1.ID, T1.Diplome, T1.Specialite, T1.Date 
    FROM   #Diplome AS T1
              INNER JOIN #Diplome AS T2
                    ON T1.ID = T2.ID
                        AND T1.Date >= T2.Date
    GROUP  BY T1.ID, T1.Date, T1.Diplome, T1.Specialite
    PS qui n'a pas grand intérêt : Je vous rassure, le champ "Date" n'est pas vraiment nommé comme cela dans ma table.

    Merci encore.

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    mai 2002
    Messages
    20 958
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 20 958
    Points : 49 766
    Points
    49 766
    Billets dans le blog
    1
    Par défaut
    Évitez tout recours à des tables temporaires ! Cela nuit gravement aux performances. Lisez l'article que j'ai écrit à ce sujet : http://blog.developpez.com/sqlpro?ti...et_persistance

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  7. #7
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    octobre 2003
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Associations - ONG

    Informations forums :
    Inscription : octobre 2003
    Messages : 87
    Points : 90
    Points
    90
    Par défaut
    Merci de la réponse.

    Il est vrai que l'utilisation d'une table temporaire n'est pas idéal. Néanmoins, je précise le but de ma requête et la volumétrie :

    Cette requête ne sera utilisée que pour une extraction de données en vue de les transférer dans une autre base. Elle ne sera lancée qu'une seule fois en théorie. En pratique, il y aura peut-être quelques tâtonnements, mais une fois les données extraites validées, la requête ne sera plus lancée.

    La requête crée une table temporaire de 1338 enregistrements sur 6 colonnes.

    Alors, même si ça n'est pas très propre, je me dis que cela en vaut quand même la chandelle. ça évite d'avoir à créer une requête trop complexe. Honte à moi

  8. #8
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : janvier 2005
    Messages : 5 826
    Points : 12 348
    Points
    12 348
    Par défaut
    Bonjour,

    Alors, même si ça n'est pas très propre, je me dis que cela en vaut quand même la chandelle. ça évite d'avoir à créer une requête trop complexe
    ça, c'est ce que vous croyez
    Prenez 5 minutes, vous n'imaginez par ce que vous ferez gagner à votre serveur et à vous en maintenance.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT COUNT(*) AS Sequence, T1.ID, T1.Diplome, T1.Specialite, T1.Date 
    FROM (
    	maRequeteDiplome
    	) AS T1
    INNER JOIN (
    		maRequeteDiplome
    	) AS T2
    ON T1.ID = T2.ID
    AND T1.Date >= T2.Date
    GROUP  BY T1.ID, T1.Date, T1.Diplome, T1.Specialite
    Plus propre encore : vous pouvez aussi faire une vue de votre requête, et ainsi remplacer maRequeteDiplome par le nom de votre vue ...

    @++

  9. #9
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    octobre 2003
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Associations - ONG

    Informations forums :
    Inscription : octobre 2003
    Messages : 87
    Points : 90
    Points
    90
    Par défaut
    Merci.

    C'est vrai qu'une Vue serait plus propre. Je n'y avais pas pensé.

    J'imagine qu'en occupation serveur, ça n'a rien à voir avec l'utilisation d'une table temporaire.

    Je vais corriger ça.
    Merci

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

Discussions similaires

  1. [Toutes versions] Requête SQL avec Simples et Doubles Quotes
    Par Roums dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 25/03/2010, 11h00
  2. Requête SQL avec une réponse unique
    Par Glutinus dans le forum Langage SQL
    Réponses: 5
    Dernier message: 06/07/2005, 17h35
  3. Problème de requête SQL avec instruction TRANSFORM
    Par Nosper dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 21/06/2005, 17h15
  4. requête SQL avec paramètre en vb avec base de donnée SQL srv
    Par dialydany dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 01/02/2005, 11h33
  5. PB requète SQL avec Interbase
    Par missllyss dans le forum InterBase
    Réponses: 2
    Dernier message: 15/07/2003, 12h37

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