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

SQL Oracle Discussion :

Jointure sur date et max


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Avril 2009
    Messages : 176
    Par défaut Jointure sur date et max
    Bonjour a tous,
    Je cherche a faire une requête qui comporte plein de petit problème et au final elle ne marche pas. Voici la structure de ma table
    Table1
    Nom1
    Date
    Caractéristique1
    Caractéristique2

    Table2
    Nom1 (clé étrangère de table 1)
    Nom 2

    Table3
    Nom1 (clé étrangère de table 1)
    Date (différente de la date de table1)
    Statut1
    Statut2

    Voila pour ce qui est de la structure.
    pour ce qui est dedans : la table3 contient énormément de champs(beaucoup plus que la table1) et la Table1 contient des caractéristiques relevé au momment date (de table1 bien sur)

    ce que je voudrais afficher :
    --Nom1--Nom2--Date--Caractéristique1--Caractéristique2--Statut1--Statut2

    la date est celle de la table1
    Pour le statut je l'obtient en prenant le dernier statut rentré avant la date de la table1 (en gros la date Maximum parmi toute les date inferieur a date de table 1)
    J'arrive a faire cela pour une date et un nom fixe grâce a une sous requête:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    select T3.STATUT1, T2.STATUT2
    from TABLE3 T3
    join TABLE2 T2 on T2.STATUS=T3.STATUT
    where T3.STATUT_DATE<to_date('010820101110','MM/DDYYYY HH24:MI')
    			and NOM1='nom1'
    			and STATE_DATE=(select max(table3.STATE_DATE)
    				from TABLE3 tab
    				where table3.NOM3='nom1'
    				and table3.DATE<to_date('010820101110','MM/DDYYYY HH24:MI'));
    Mais je n'arrive pas à insérer cette requête dans ma requête prééxistante (car j'ai déjà une requète qui existe pour obtenir la même chose sans les statuts) pour obtenir ce que je veux et faire le lien avec la table1.

    Pour info, j'ai testé avec cette requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    select T1.NOM1,T2.NOM2
    	 T3.STATUT1
    from Table1 T1
    join TABLE2 T2 on T2.NOM1=T1.Nom1
    join TABLE3 T3 on T3.NOM1=T1.NOM1
    where T3.DATE=(select max(table3.DATE)
    					from TABLE3 T4			where table4.STATE_DATE<T1.DATE)
    											;
    Mais la requête tourne vraiment très longtemps sans rien renvoyé (en tout cas je l'arrète avant)

    Pourriez vous m'aidez si vous comprenez ce que j'aimerais obtenir.
    Merci d'avance pour votre aide

  2. #2
    Membre Expert Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Par défaut
    Ce n'est pas simple de manipuler des dates en cherchant le dernier statut. Je ferais ça avec une fonction analytique.

    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
    select
    Table1.Nom1, T2.Statut1, T2.Statut2, Table1.Date
    from
    (
    select
    distinct
    Nom1,
    Statut1,
    Statut2,
    Date,
    dense_rank() over (partition by Nom1 order by Date desc) "position"
    from Table3,
    (
    select Nom1, Date "day" from Table1
    ) T1
    where Date<= T1."day"
    and Nom1 = T1.Nom1
    ) T2, Table1
    where "position" = 1
    and Table1.Nom1 = T2.Nom1
    Mais je pense qu'il existe une fonction analytique plus adaptée que celle que j'ai utilisée, on va voir si Waldar passe par ici.

    Edit:
    correction cf plus bas.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Avril 2009
    Messages : 176
    Par défaut
    Merci beaucoup pour ta formule, effectivement ce n'est pas simple.
    Ta formule marche presque parfaitement mais je ne comprend pas pourquoi, pour la faire marcher je suis obliger de supprimer le dernier champs du select (T1.Date), j'ai essayé de le remplacé par T1."Day", rien n'y fait j'ai une erreur invalid indentifier.
    As-tu une idée d'où cela peut venir?

  4. #4
    Membre Expert Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Par défaut
    Oui, "day" est juste utile dans la sous-requête, pour afficher les éléments de Table1 j'y refais appel plus haut. Si Table1 est une énorme table on peut effectivement faire remonter les informations 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
    SELECT
    T2.Nom1, T2.Statut1, T2.Statut2, T2."day"
    FROM
    (
    SELECT
    DISTINCT
    Nom1,
    Statut1,
    Statut2,
    Date,
    dense_rank() over (partition BY Nom1 ORDER BY Date DESC) "position",
    T1."day"
    FROM Table3,
    (
    SELECT Nom1, Date "day" FROM Table1
    ) T1
    WHERE Date<= T1."day"
    AND Nom1 = T1.Nom1
    ) T2
    WHERE "position" = 1
    C'est 2 logiques différentes, la 2e étant potentiellement plus performante mais moins facile à maintenir.

    EDIT:
    erreur de ma part, ce n'est pas T1.Date qu'il faut dans la première requête mais Table1.Date. Je corrige.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Avril 2009
    Messages : 176
    Par défaut
    Sa à l'air de marcher impécablement , merci beaucoup de ton aide.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Avril 2009
    Messages : 176
    Par défaut
    J'ai en faite crié victoire un peu vite la requète ne me renvoie qu'un nombre très limité de resultat par rapport a ce qu'elle devrait (je ne m'en suit pas rendue compte tout de suite car le nombre de résultat renvoyé reste très grand). Je n'ai pas autant de ligne renvoyé que d'entité dans table1 (ce qui est mon objectif initial).
    J'ai essayé de supprimé le distinct mais sa ne change quasiment rien. D'où cela peut-il venir?

  7. #7
    Membre Expert Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Par défaut
    Je dirais qu'il existe des Table1.Nom1 qui n'ont pas de correspondance dans Table2 ou Table3. Ou du moins qui n'ont pas de correspondance dans Table3 pour les critères de date spécifiés.

    Dans ce cas il suffit de reprendre ma requête avec une jointure ouverte :
    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
    SELECT
    Table1.Nom1, T2.Statut1, T2.Statut2, Table1.Date
    FROM
    Table1
    left outer join
    (
    SELECT
    DISTINCT
    Nom1,
    Statut1,
    Statut2,
    Date,
    dense_rank() over (partition BY Nom1 ORDER BY Date DESC) "position"
    FROM Table3,
    (
    SELECT Nom1, Date "day" FROM Table1
    ) T1
    WHERE Date<= T1."day"
    AND Nom1 = T1.Nom1
    ) T2
    on ( Table1.Nom1 = T2.Nom1 and T2."position" = 1 )

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Avril 2009
    Messages : 176
    Par défaut
    Cette fois sa marche vraiment. Merci d'avoir pris le temps de m'aider. Cette requète était vraiment complexe. Merci beaucoup.

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

Discussions similaires

  1. jointures sur des dates et invites dans l'univers
    Par stamia dans le forum Designer
    Réponses: 1
    Dernier message: 27/05/2011, 16h50
  2. [Vxi] Auto-jointure sur max date
    Par Burt67 dans le forum Designer
    Réponses: 2
    Dernier message: 02/02/2011, 16h52
  3. Filtre sur date max
    Par Fox1977 dans le forum Designer
    Réponses: 9
    Dernier message: 06/10/2010, 14h29
  4. Réponses: 16
    Dernier message: 14/04/2006, 18h38
  5. MAX et Jointure sur les données correspondantes
    Par lepeule dans le forum Langage SQL
    Réponses: 1
    Dernier message: 12/04/2006, 16h18

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