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 :

Requête Date Max


Sujet :

MS SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2014
    Messages : 7
    Par défaut Requête Date Max
    Bonjour,

    Dans le cadre d'un projet, je dois créer une vue qui va accéder à plusieurs table pour y récupérer plusieurs informations. Je cherche donc à faire une requête qui va récupérer les enregistrements qui ont la date la plus récente, jusque là, rien de bien compliqué.

    Ma table se compose comme ceci

    Id | IdIndi | DateDeb | DateFin
    __|______|_________|_______
    1 |PPOP |2013-01-02 | 2013-31-02
    2 |PPOP |2013-01-12 | 2013-31-12
    3 |CCMP |2013-01-02 | 2013-31-02
    4 |CCMP |2013-01-04 | 2013-31-04
    5 |CCMP |2013-01-05 | 2013-31-05
    6 |RTP |2013-01-02 | 2013-31-02

    Mais, ma Vue accède également à des données de d'autres tables..
    J'aimerais donc là sortir :

    2 |PPOP |2013-01-12 | 2013-31-12
    5 |CCMP |2013-01-05 | 2013-31-05
    6 |RTP |2013-01-02 | 2013-31-02

    Mais, dans mon cas, j'ai le droit à plus de résultat que prévu.

    Ma Vue pour le moment est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT DISTINCT 
                          TOP (100) PERCENT dbo.Mesure.Resultat_MES, dbo.Mesure.QuantiteNum_MES, dbo.Mesure.QuantiteDenum_MES, dbo.InfoMesure.IdIndicateur_IM, 
                          dbo.InfoMesure.DateDeb_IM, dbo.NiveauDonnee.NomNiveau_NIV, dbo.ValeurCible.Socle_VC, dbo.ValeurCible.Point_VC, dbo.ValeurCible.Objectif_VC, 
                          dbo.InfoMesure.DateFin_IM
    FROM         (SELECT     MAX(DateFin_IM) AS DateRecente, IdIndicateur_IM
                           FROM          dbo.InfoMesure AS InfoMesure_1
                           GROUP BY IdIndicateur_IM) AS TestDate INNER JOIN
                          dbo.InfoMesure ON TestDate.DateRecente = dbo.InfoMesure.DateFin_IM INNER JOIN
                          dbo.Mesure ON dbo.Mesure.IdInfoMesure_MES = dbo.InfoMesure.IdInfoMesure_IM INNER JOIN
                          dbo.NiveauDonnee ON dbo.InfoMesure.IdNiveau_IM = dbo.NiveauDonnee.IdNiveau_NIV INNER JOIN
                          dbo.InfoValeurCible ON dbo.NiveauDonnee.IdNiveau_NIV = dbo.InfoValeurCible.IdNiveau_IV INNER JOIN
                          dbo.ValeurCible ON dbo.InfoValeurCible.IdInfoValeurCible_IV = dbo.ValeurCible.IdInfoValeurCible_VC INNER JOIN
                          dbo.Indicateur ON dbo.InfoMesure.IdIndicateur_IM = dbo.Indicateur.IdIndicateur_IND AND dbo.InfoValeurCible.IdIndicateur_IV = dbo.Indicateur.IdIndicateur_IND
    ORDER BY dbo.InfoMesure.IdIndicateur_IM
    Et ensuite, pour les plus aguéris d'entre vous, j'aimerais également sortir avec cette vue la DateRécente-1, pour faire ensuite un comparatif d'évolutions des informations récupérés. Dans l'exemple si dessus, sortir donc :

    1 |PPOP |2013-01-02 | 2013-31-02
    2 |PPOP |2013-01-12 | 2013-31-12
    4 |CCMP |2013-01-04 | 2013-31-04
    5 |CCMP |2013-01-05 | 2013-31-05
    6 |RTP |2013-01-02 | 2013-31-02


    Si quelqu'un peut m'aider, ou au besoin que je donne plus d'informations.
    Cordialement, Chewby.

  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
    Par défaut
    Bonjour,

    Vous pouvez utiliser les fonctions 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
    14
    15
    16
     
    WITH Tmp AS (
     SELECT
        Id
        ,IdIndi
        , DateDeb
        , DateFin
        ,RANK() OVER(PARTITION BY IdIndi ORDER BY DateDebut DESC) AS Rang
     FROM LaTable
    )
    SELECT 
        Id
        ,IdIndi
        , DateDeb
        , DateFin
    FROM Tmp <= 2 --ou : = 1 pour n'avoir qu'une ligne par IdIndi

  3. #3
    Membre Expert
    Avatar de rudib
    Homme Profil pro
    Fakir SQL Server & NoSQL
    Inscrit en
    Mai 2006
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Fakir SQL Server & NoSQL

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 573
    Par défaut
    Etape n°1, j'ai commencé à réécrire ta vue (le générateur graphique c'est sympa, mais ça ne donne pas un résultat très lisible.
    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
    ;WITH cte as (
    	SELECT 
    		MAX(DateFin_IM) AS DateRecente,
    		DATEADD(day, -1, MAX(DateFin_IM)) AS DateRecenteMoins1,
    		IdIndicateur_IM
        FROM dbo.InfoMesure AS InfoMesure_1
    	GROUP BY IdIndicateur_IM
    )
    SELECT DISTINCT TOP (100) PERCENT 
    	m.Resultat_MES, 
    	m.QuantiteNum_MES, 
    	m.QuantiteDenum_MES, 
    	im.IdIndicateur_IM, 
    	im.DateDeb_IM, 
    	nd.NomNiveau_NIV, 
    	vc.Socle_VC, 
    	vc.Point_VC, 
    	vc.Objectif_VC, 
    	im.DateFin_IM
    FROM cte AS TestDate 
    JOIN dbo.InfoMesure im ON TestDate.DateRecente = im.DateFin_IM 
    JOIN dbo.Mesure m ON m.IdInfoMesure_MES = im.IdInfoMesure_IM 
    JOIN dbo.NiveauDonnee nd ON im.IdNiveau_IM = nd.IdNiveau_NIV 
    JOIN dbo.InfoValeurCible ivc ON nd.IdNiveau_NIV = ivc.IdNiveau_IV 
    JOIN dbo.ValeurCible vc ON ivc.IdInfoValeurCible_IV = vc.IdInfoValeurCible_VC 
    JOIN dbo.Indicateur i ON im.IdIndicateur_IM = i.IdIndicateur_IND AND ivc.IdIndicateur_IV = i.IdIndicateur_IND
    ORDER BY im.IdIndicateur_IM
    Donc tu dis que tu as plus de résultats que prévu ? C'est-à-dire ? Des doublons ? Fais simplement un SELECT * :
    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 
    		MAX(DateFin_IM) AS DateRecente,
    		DATEADD(day, -1, MAX(DateFin_IM)) AS DateRecenteMoins1,
    		IdIndicateur_IM
        FROM dbo.InfoMesure AS InfoMesure_1
    	GROUP BY IdIndicateur_IM
    )
    SELECT *
    FROM cte AS TestDate 
    JOIN dbo.InfoMesure im ON TestDate.DateRecente = im.DateFin_IM 
    JOIN dbo.Mesure m ON m.IdInfoMesure_MES = im.IdInfoMesure_IM 
    JOIN dbo.NiveauDonnee nd ON im.IdNiveau_IM = nd.IdNiveau_NIV 
    JOIN dbo.InfoValeurCible ivc ON nd.IdNiveau_NIV = ivc.IdNiveau_IV 
    JOIN dbo.ValeurCible vc ON ivc.IdInfoValeurCible_IV = vc.IdInfoValeurCible_VC 
    JOIN dbo.Indicateur i ON im.IdIndicateur_IM = i.IdIndicateur_IND AND ivc.IdIndicateur_IV = i.IdIndicateur_IND
    ORDER BY im.IdIndicateur_IM
    là où tu verras des informations qui diffèrent dans les valeurs de colonnes sur des lignes doublonnées, cela te donnera l'indication que quelle table dans tes jointures génère des doublons. Car s'il y a doublons cela provient sans doute d'une table dans les jointures.

  4. #4
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2014
    Messages : 7
    Par défaut
    Bonjour et merci des réponses !

    @aieeeuuuuu : Merci, il faudrait que je me documente un peu sur le fenêtrage, car je ne l'ai pas encore vu en cours (2ème année de BTS SIO option SLAM).

    @rudib : Suite à l'exécution de la première requête :

    370 lignes sortie, absence de certain IdIndicateur qui normalement devrait-être présent, et j'ai toutes les DateFin de chaque IdIndicateur, donc pas seulement les plus récentes.

    Suite à l'exécution de la seconde requête :

    1240 lignes sortie, pour chaque IdIndicateur_IM de cte est associé un IdIndicateur_IM de la table im, ce sont les IdIndicateur de dessus (avec les absents, suis-je clair ?).

    Je pense qu'enfaite ma vue prend pour chaque ligne, chaque IdIndicateur ayant comme DateFin la DateFin d'un autre IdIndicateur, car un IdIndicateur peut avoir plusieurs DateFin différente (car généralement mensuel), alors qu'il me faudrait récupérer pour chaque IdIndicateur SA DateFin la plus récente, la dernière entrée dans la base.

  5. #5
    Membre Expert
    Avatar de rudib
    Homme Profil pro
    Fakir SQL Server & NoSQL
    Inscrit en
    Mai 2006
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Fakir SQL Server & NoSQL

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 573
    Par défaut
    donc :
    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
    ;WITH cte AS (
    	SELECT 
    		MAX(DateFin_IM) AS DateRecente,
    		DATEADD(day, -1, MAX(DateFin_IM)) AS DateRecenteMoins1,
    		IdIndicateur_IM
        FROM dbo.InfoMesure AS InfoMesure_1
    	GROUP BY IdIndicateur_IM
    )
    SELECT DISTINCT TOP (100) PERCENT 
    	m.Resultat_MES, 
    	m.QuantiteNum_MES, 
    	m.QuantiteDenum_MES, 
    	im.IdIndicateur_IM, 
    	im.DateDeb_IM, 
    	nd.NomNiveau_NIV, 
    	vc.Socle_VC, 
    	vc.Point_VC, 
    	vc.Objectif_VC, 
    	im.DateFin_IM
    FROM cte AS TestDate 
    JOIN dbo.InfoMesure im ON TestDate.DateRecente = im.DateFin_IM AND cte.IdIndicateur_IM = im.IdIndicateur_IM
    JOIN dbo.Mesure m ON m.IdInfoMesure_MES = im.IdInfoMesure_IM 
    JOIN dbo.NiveauDonnee nd ON im.IdNiveau_IM = nd.IdNiveau_NIV 
    JOIN dbo.InfoValeurCible ivc ON nd.IdNiveau_NIV = ivc.IdNiveau_IV 
    JOIN dbo.ValeurCible vc ON ivc.IdInfoValeurCible_IV = vc.IdInfoValeurCible_VC 
    JOIN dbo.Indicateur i ON im.IdIndicateur_IM = i.IdIndicateur_IND AND ivc.IdIndicateur_IV = i.IdIndicateur_IND
    ORDER BY im.IdIndicateur_IM;

  6. #6
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2014
    Messages : 7
    Par défaut
    Alors la requête me renvoi : 79 résultats alors qu'il m'en faut 83.

    Il y a aussi des doublons car par exemple pour mon premier IdIndicateur j'ai :
    PPOP 2013-10-01 Nationnal
    PPOP 2012-10-01 Nationnal

    Alors que je devrais avoir 1 Ligne pour PPOP Nationnal et 1 Ligne pour PPOP Local/Regional.

    Et il me manque toujours certains IdIndicateur qui devrait être présent.

    De plus, dans le WITH j'ai rajouté :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ;WITH cte AS (
    	SELECT 
    		MAX(DateFin_IM) AS DateRecente,
    		DATEADD(day, -1, MAX(DateFin_IM)) AS DateRecenteMoins1,
    		IdIndicateur_IM, IdNiveau_IM
        FROM dbo.InfoMesure AS InfoMesure_1
    	GROUP BY IdIndicateur_IM, IdNiveau_IM
    )
    Car un IdIndicateur à plusieurs Niveau (1 à 3), et il me faut chaque IdIndicateur pour chaque Niveau (ex : PPOP 1 DateFinRecente | PPOP 2 DateFinRecente | CPMA 3 DateFinRecente | LOLE 2 DateFinRecente | LOLE 3 DateFinRecente).

    Cette requête seul me renvoi 83 résultats, soit les 83 que je devrais avoir.

  7. #7
    Membre Expert
    Avatar de rudib
    Homme Profil pro
    Fakir SQL Server & NoSQL
    Inscrit en
    Mai 2006
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Fakir SQL Server & NoSQL

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 573
    Par défaut
    bon, attends, là ça devient indécent Il faut que tu regardes toi-même le schéma de ta base et que tu identifies les bonnes clauses de jointure. C'est la base de la base. Je ne peux pas résoudre tous les problèmes de ta requête à ta place, en plus sans avoir le schéma ni les données.

    Commence avec ce squelette :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ;WITH cte AS (
    	SELECT 
    		MAX(DateFin_IM) AS DateRecente,
    		DATEADD(day, -1, MAX(DateFin_IM)) AS DateRecenteMoins1,
    		IdIndicateur_IM, IdNiveau_IM
        FROM dbo.InfoMesure AS InfoMesure_1
    	GROUP BY IdIndicateur_IM, IdNiveau_IM
    )
    SELECT *
    FROM cte AS TestDate 
    JOIN dbo.InfoMesure im ON TestDate.DateRecente = im.DateFin_IM AND cte.IdIndicateur_IM = im.IdIndicateur_IM
    	AND cte.IdNiveau_IM = im.IdNiveau_IM
    et ajoute petit à petit tes jointures pour voir s'il y en a une qui t'enlève des données. Ce sont des jointures internes, elles sont discriminantes.

Discussions similaires

  1. Réponses: 2
    Dernier message: 24/08/2012, 16h39
  2. Requête date max, date précédente et valeurs associées
    Par Nitromard dans le forum Requêtes et SQL.
    Réponses: 6
    Dernier message: 15/07/2011, 08h39
  3. Requête SQL : Groupement et date max
    Par ppve03651 dans le forum Développement
    Réponses: 4
    Dernier message: 23/12/2010, 08h44
  4. Requête avec une date max
    Par xehyan dans le forum Langage SQL
    Réponses: 4
    Dernier message: 20/05/2009, 10h21
  5. Requête avec max date et champs correspondants
    Par sl1980 dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 23/09/2007, 00h01

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