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

Langage SQL Discussion :

[Access] requête de sélection complexe


Sujet :

Langage SQL

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2004
    Messages : 93
    Points : 61
    Points
    61
    Par défaut [Access] requête de sélection complexe
    Bonjour,

    j'ai une table simple :

    Table (Date, IdPersonne)

    avec les 2 colonnes faisant office de clé (histoire qu'une personne n'est qu'un seul record par jour)

    exemple de contenu :

    Date | IdPersonne
    ---------------------
    01/01/2006| 1
    02/01/2006| 1
    03/01/2006| 1
    04/01/2006| 1
    01/02/2006| 2
    02/02/2006| 2
    03/02/2006| 2
    15/02/2006| 1
    16/02/2006| 1
    17/02/2006| 1

    je voudrai obtenir les périodes des différentes personnes :

    ce qui donne :

    Personne 1:
    01/01/2006 - 04/01/2006
    15/02/2006 - 17/02/2006
    Personne 2:
    01/02/2006 - 03/02/2006

    (malgré mon scepticisme, et après un brain storming de fou)
    Y a t-il un moyen d'obtenir ce type de résultat en SQL à partir de cette table ??

  2. #2
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Essaye :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select IdPersonne, min(laDate), max(laDate)
    from laTable
    group by IdPersonne

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2004
    Messages : 93
    Points : 61
    Points
    61
    Par défaut
    j'obtiens :

    Personne 1:
    01/01/2006 - 17/02/2006
    Personne 2:
    01/02/2006 - 03/02/2006

    alors qu'il faudrai :

    Personne 1:
    01/01/2006 - 04/01/2006
    15/02/2006 - 17/02/2006
    Personne 2:
    01/02/2006 - 03/02/2006


  4. #4
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    La réponse ne sera pas la même selon que tu utilises :

    1. ORACLE
    2. Un moteur implémentant WITH RECURSIVE
    3. Ni l'un ni l'autre
    Il est donc impératif que tu donnes le moteur que tu utilises et a version (cf. les règles de ce forum)

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2004
    Messages : 93
    Points : 61
    Points
    61
    Par défaut
    euh... access

  6. #6
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 126
    Points : 28 535
    Points
    28 535
    Par défaut
    Pas sur que tout passe sous Access, mais dans l'absolu ça donnerait ça :
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    -- Donne la date de début de période 
    CREATE  VIEW  Debut
    AS  SELECT  Personne
              , Date  AS  Debut 
        FROM  MaTable AS  T1
        WHERE NOT EXISTS  (SELECT 1
          FROM  MaTable AS  T2
          WHERE T1.Personne = T2.Personne
            AND T1.Date     = T2.Date - 1
            )
    ;
     
    -- Donne la date de fin de période
    CREATE  VIEW  Fin
    AS  SELECT  Personne
              , Date  AS  Fin 
        FROM  MaTable AS  T1
        WHERE NOT EXISTS  (SELECT 1
          FROM  MaTable AS  T2
          WHERE T1.Personne = T2.Personne
            AND T1.Date     = T2.Date - 1
            )
    ;
     
    -- Donne un numéro d'ordre à la période 
    CREATE  VIEW  OrdreDebut
    AS  SELECT  Personne
              , Debut
              , ( SELECT  COUNT(*)  + 1
                  FROM  Debut AS D2
                  WHERE D1.Personne = D2.Personne
                    AND D1.Debut  >=  D2.Debut
                ) AS  Ordre
        FROM  Debut AS D1
    ;
     
    -- Donne un numéro d'ordre à la période 
    CREATE  VIEW  OrdreFin
    AS  SELECT  Personne
              , Fin
              , ( SELECT  COUNT(*)  + 1
                  FROM  Fin AS D2
                  WHERE D1.Personne = D2.Personne
                    AND D1.Fin    >=  D2.Fin
                ) AS  Ordre
        FROM  Fin AS D1
    ;
     
    --  Regroupe le tout
    SELECT  Personne
          , Debut
          , Fin
    FROM  OrdreDebut  AS  D
      INNER JOIN  OrdreFin  AS  F
        ON  D.Personne  = F.Personne
        AND D.Ordre     = F.Ordre
    ;
    PS: Je n'ai pas les moyens de tester... mais c'était amusant à réfléchir (15')

  7. #7
    Membre expert
    Avatar de TheLeadingEdge
    Inscrit en
    Mai 2005
    Messages
    1 199
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 1 199
    Points : 3 103
    Points
    3 103
    Par défaut
    Bonjour,

    Sympa ton petit casse-tete.
    je te propose ca (pas forcément optimisé ;-) ) qui tourne ds sqlserver.

    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
    SELECT 	d.ladate,
    	MAX(COALESCE(f.ladate,d.ladate)),
    	d.lapersonne
    FROM	latable AS d
    LEFT OUTER JOIN latable AS f
    ON 	f.lapersonne = d.lapersonne
    WHERE NOT EXISTS
    (
    SELECT	ladate
    FROM	latable
    WHERE    lapersonne = d.lapersonne
    AND	ladate + 1 = d.ladate
    )
    AND	CAST (COALESCE(f.ladate,d.ladate) - d.ladate + 1 AS NUMERIC) =
    	(
    	SELECT	COUNT(1) 
    	FROM	latable
    	WHERE	lapersonne = d.lapersonne
    	AND	ladate BETWEEN d.ladate AND (COALESCE(f.ladate,d.ladate))
    	)
    GROUP BY d.ladate,
    	d.lapersonne
    ;
    A +

    [EDIT]le meme en msaccess
    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 d.ladate,
    MAX(NZ(f.ladate,d.ladate)),
    d.lapersonne
    FROM latable AS d 
    LEFT JOIN latable AS f
    ON  f.lapersonne = d.lapersonne
    WHERE NOT EXISTS
    (
    SELECT ladate
    FROM latable
    WHERE lapersonne = d.lapersonne
    AND ladate + 1 = d.ladate
    )
    AND CInt (NZ(f.ladate,d.ladate) - d.ladate + 1) =
    (
    SELECT COUNT(1) 
    FROM latable
    WHERE lapersonne = d.lapersonne
    AND ladate BETWEEN d.ladate AND (NZ(f.ladate,d.ladate))
    )
    GROUP BY d.ladate, d.lapersonne;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ladate	lapersonne
    01/01/2006	1
    02/01/2006	1
    03/01/2006	1
    04/01/2006	2
    01/02/2006	2
    03/02/2006	2
    15/02/2006	1
    16/02/2006	1
    17/02/2006	1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ladate	Expr1001	             lapersonne
    01/01/2006	03/01/2006	1
    04/01/2006	04/01/2006	2
    01/02/2006	01/02/2006	2
    03/02/2006	03/02/2006	2
    15/02/2006	17/02/2006	1
    [/EDIT]

  8. #8
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Très belle solution TheLeadingEdge .
    Néanmoins on peut la simplifier un tout petit peu : le LEFT OUTER JOIN du début est inutile, un INNER JOIN suffit, donc les COALESCE sont inutiles.

Discussions similaires

  1. Pb migration Access / SQL server
    Par yoyo dans le forum MS SQL Server
    Réponses: 10
    Dernier message: 25/04/2005, 11h39
  2. [CR][Access] intégrer un viewer dans un formulaire access
    Par nicolak dans le forum SAP Crystal Reports
    Réponses: 7
    Dernier message: 13/01/2003, 16h52
  3. perl et access
    Par dechoc dans le forum Modules
    Réponses: 3
    Dernier message: 10/08/2002, 21h02
  4. associer une base de données(access) a un dbgrid
    Par ange1708 dans le forum MFC
    Réponses: 3
    Dernier message: 11/06/2002, 13h18
  5. Réponses: 3
    Dernier message: 22/05/2002, 10h37

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