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

Requêtes MySQL Discussion :

jointure d'une table sur elle même


Sujet :

Requêtes MySQL

  1. #1
    Futur Membre du Club
    Inscrit en
    Septembre 2002
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 16
    Points : 7
    Points
    7
    Par défaut jointure d'une table sur elle même
    Bonjour à tous,
    après plusieurs essais infructueux, je vous soumet mon problème de requête :

    soit une table T avec
    - un champs tu (bigint) qui est un temps epochs
    - un champs val (double) qui est une valeur.

    Je souhaiterais obtenir en résultat de requête la représentation suivante
    tu_start, count_val_jour, count_val_heure.

    avec tu_start représenté heure par heure,
    count_val_jour : nombre de valeurs acquises sur la journée et
    count_val_heure : nombre de valeurs acquises en 1 heure.
    Pour une journée il doit donc y avoir répétition de 24 fois la valeur de count_val_jour dans le résultat de la requête.

    soit :
    tu_start+00 count_val_jour_1 count_val_heure(x)
    tu_start+01 count_val_jour_1 count_val_heure(y)
    tu_start+02 count_val_jour_1 count_val_heure(z)
    ...
    tu_start+25 count_val_jour_2 count_val_heure(a)
    tu_start+26 count_val_jour_2 count_val_heure(b)
    tu_start+27 count_val_jour_2 count_val_heure(c)
    ...



    L'idée ensuite est de pouvoir vérifier que pour chaque intervalle de 1 heure:
    count_val_heure x 24 ~ count_val_jour et vérifier ainsi des "trous" d'acquisition de mesures.

    Pour cela j'ai :

    la requête pour avoir le comptage par heure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    select SQL_BIG_RESULT 
    from_unixtime(min(T.`tu`)) AS 'tu_start',
    count(T.`val`) as 'count_val_heure'
    from T
    group by from_unixtime(T.`tu`, '%Y-%m-%d %H')
    order by tu_start asc
    la requête pour avoir le comptage par jour:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    select SQL_BIG_RESULT 
    from_unixtime(min(T.`tu`)) AS 'tu_start',
    count(T.`val`) as 'count_val_jour'
    from T
    group by from_unixtime(T.`tu`, '%Y-%m-%d')
    order by tu_start asc
    Mon problème est de "lier" ces 2 requêtes, j'imagine qu'il faut passer par une jointure de la table T avec elle-même mais pour le moment je n'ai pas réussi...

    Si quelqu'un a un conseil à me fournir,
    Merci d'avance.
    Fred!

  2. #2
    Futur Membre du Club
    Inscrit en
    Septembre 2002
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Bon je me réponds en partie à moi même, après avoir "découvert" les tables temporaires : une solution à mon problème serait :

    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
     
    DROP TEMPORARY TABLE IF EXISTS T_TEMP;
     
    CREATE TEMPORARY TABLE T_TEMP
    SELECT 
    from_unixtime(min(T.`tu`),'%Y-%m-%d') AS 'TuStart',
    count(*) AS 'count_val_jour'
    FROM T
    GROUP BY from_unixtime(T.`tu`, '%Y-%m-%d')
    ORDER BY TuStart ASC;
     
    SELECT 
    from_unixtime(min(T.`tu`)) AS 'TuStart',
    count_val_jour,
    count(*) AS 'count_val_heure'
    FROM T join T_TEMP on from_unixtime(T.`tu`, '%Y-%m-%d') = T_TEMP.TuStart
    GROUP BY from_unixtime(T.`tu`, '%Y-%m-%d %H')
    ORDER BY TuStart ASC;
    Je maintiens néanmoins ma question : peut-on faire la même chose sans passer par une table temporaire ?

  3. #3
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Bonjour,

    oui avec des sous-requêtes

  4. #4
    Futur Membre du Club
    Inscrit en
    Septembre 2002
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Bon ben voila pour ceux que cela pourrait intéresser :
    en ré-organisant la requête qui utilisait la table temporaire on obtient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT from_unixtime(min(T.`tu`)) AS 'tu_start',
    count_val_jour,
    count(*) AS 'count_val_heure'
    FROM T join 
    (
    	SELECT from_unixtime(min(T.`tu`),'%Y-%m-%d') AS 'tu_start',
    	count(*) AS 'count_val_jour'
    	FROM T
    	GROUP BY from_unixtime(T.`tu`, '%Y-%m-%d')
    ) as T_TEMP
    on from_unixtime(T.`tu`, '%Y-%m-%d') = T_TEMP.tu_start
    GROUP BY from_unixtime(T.`tu`, '%Y-%m-%d %H')
    ORDER BY tu_start ASC;
    Cela fonctionne et en plus c'est un peu plus rapide.

  5. #5
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    en passant par 2 sous-requêtes le resultat pourrai être encore plus rapide, je penses.

    Là vous démultipliez les solutions pour ensuite les restreindre.

  6. #6
    Futur Membre du Club
    Inscrit en
    Septembre 2002
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par punkoff Voir le message
    en passant par 2 sous-requêtes le resultat pourrai être encore plus rapide, je penses.

    Là vous démultipliez les solutions pour ensuite les restreindre.
    N'étant pas trop expérimenté en "sql" je veux bien un exemple ?
    Merci d'avance.

  7. #7
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    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
     
    SELECT T_TEMP2.'tu_start',
    count_val_jour,
    count_val_heure
    FROM 
    (
    	SELECT from_unixtime(min(T.`tu`),'%Y-%m-%d') AS 'tu_start',
    	count(*) AS 'count_val_jour'
    	FROM T
    	GROUP BY from_unixtime(T.`tu`, '%Y-%m-%d')
    ) AS T_TEMP
    inner join 
    (
    	SELECT from_unixtime(min(T.`tu`)) AS 'tu_start', count(*) AS 'count_val_heure'
    	from T
    	GROUP BY from_unixtime(T.`tu`, '%Y-%m-%d %H')
    ) as T_TEMP2 on T_TEMP.'tu_start' = from_unixtime(T_TEMP2.'tu_start', '%Y-%m-%d')
    ORDER BY tu_start ASC;

  8. #8
    Futur Membre du Club
    Inscrit en
    Septembre 2002
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    > punkoff : merci je vais tester cela.

  9. #9
    Futur Membre du Club
    Inscrit en
    Septembre 2002
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Juste une modification à faire pour le 'ON' :
    Citation Envoyé par punkoff Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    as T_TEMP2 on T_TEMP.'tu_start' = from_unixtime(T_TEMP2.'tu_start', '%Y-%m-%d')
    ->
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    as T_TEMP2 on day(T_TEMP.'tu_start') = day(T_TEMP2.'tu_start')
    Et ça marche nickel.
    Temps d’exécution de la requête sur mon jeu de données : ~2.3s contre ~8.1s avant !!!

    Un Grand Merci.

    Fred!

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

Discussions similaires

  1. [Modèle Relationnel] jointure d'une table avec elle-même
    Par johnny3 dans le forum Schéma
    Réponses: 11
    Dernier message: 26/04/2015, 00h15
  2. Relation d'une table sur elle-même ?
    Par TallyHo dans le forum Requêtes
    Réponses: 2
    Dernier message: 30/10/2007, 00h14
  3. Probleme jointure d'une table sur elle même
    Par fred64 dans le forum Langage SQL
    Réponses: 4
    Dernier message: 18/05/2006, 15h01
  4. [SQL2K] delete cascade d'une table sur elle même
    Par StormimOn dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 25/04/2006, 16h28
  5. [arborescence] jointure d'une table avec elle même ?
    Par Celelibi dans le forum Requêtes
    Réponses: 2
    Dernier message: 16/11/2004, 18h48

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