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 et SQL. Discussion :

Union (avec comptes) sur 6 colonnes identiques dans une même table [AC-2016]


Sujet :

Requêtes et SQL.

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 134
    Points : 53
    Points
    53
    Par défaut Union (avec comptes) sur 6 colonnes identiques dans une même table
    Bonjour,

    Voilà 3 jours que j'essaie de coder une requête portant sur 6 colonnes d'une même table. En vain, je ne récolte que des alertes d'impossibilité...
    J'ai pas mal réfléchis à cette astucieuse réflexion, mais sans réussite.
    Je présente en 1 la structure de la table, en 2 la requête telle que je bloque, en 3 les données de son rendu, et en 4 les données espérées.

    1 - table
    clé IndividuS1 IndividuS2 IndividuS3 IndividuT1 IndividuT2 IndividuT3
    1 A - - - - -
    2 A B - - - -
    3 B A - - - -
    4 A C B - - -
    5 C A - - - -
    6 C - - - - -
    7 - - - D - -
    8 - - - E - -
    9 - - - E A -

    2 - requête d'échec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT IndividuS1 AS Individu, Count(*) AS Compte FROM Table GROUP BY IndividuS1
    UNION ALL
    SELECT IndividuS2 AS Individu, Count(*) AS Compte FROM Table GROUP BY IndividuS2
    UNION ALL
    SELECT IndividuS3 AS Individu, Count(*) AS Compte FROM Table GROUP BY IndividuS3
    UNION ALL
    SELECT IndividuT1 AS Individu, Count(*) AS Compte FROM Table GROUP BY IndividuT3 
    UNION ALL
    SELECT IndividuT2 AS Individu, Count(*) AS Compte FROM Table GROUP BY IndividuT2
    UNION ALL
    SELECT IndividuT3 AS Individu, Count(*) AS Compte FROM Table GROUP BY IndividuT3;
    3 - résultats avec cette mauvaise requête (pas de changement avec Union ou Union All)
    Individu Compte
    A 3 => compte en S1
    A 2 => compte en S2
    A 1 => compte en T2
    B 1 => compte en S1
    B 1 => compte en S2
    B 1 => compte en S3
    C 2 => compte en S1
    C 1 => compte en S2
    D 1 => compte en T1
    E 2 => compte en S1
    - 3 => compte en S1
    - 5 => compte en S2
    - 8 => compte en S3
    - 6 => compte en T1
    - 8 => compte en T2
    - 9 => compte en T3

    4 - résultats recherchés
    Individu Compte
    A 6 => compte en S1, S2, T2
    B 3 => compte en S1, S2, S3
    C 3 => compte en S1, S2
    D 1 => compte en T1
    E 2 => compte en S1
    - 39 => compte en S1, S2, S3, T1, T2, T3



    Avec grand respect et remerciement à qui saura trouver une piste,
    Bk

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    voici une solution possible :

    1) Créer la requête suivante et la nommer "rIndividus"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT Nz([IndividuS1],"-") & Nz([IndividuS2],"-") & Nz([IndividuS3],"-") & Nz([IndividuT1],"-") & Nz([IndividuT2],"-") & Nz([IndividuT3],"-") AS Individus
    FROM Table
    2) la requête final qui utilise la 1ère :
    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
     
    SELECT "A" AS Individu, Sum(Len([Individus])-Len(Replace([Individus],[Individu],""))) AS Compte
    FROM rIndividus
    GROUP BY "A"
    UNION
    SELECT "B" AS Individu, Sum(Len([Individus])-Len(Replace([Individus],[Individu],""))) AS Compte
    FROM rIndividus
    GROUP BY "B"
    UNION
    SELECT "C" AS Individu, Sum(Len([Individus])-Len(Replace([Individus],[Individu],""))) AS Compte
    FROM rIndividus
    GROUP BY "C"
    UNION
    SELECT "D" AS Individu, Sum(Len([Individus])-Len(Replace([Individus],[Individu],""))) AS Compte
    FROM rIndividus
    GROUP BY "D"
    UNION
    SELECT "E" AS Individu, Sum(Len([Individus])-Len(Replace([Individus],[Individu],""))) AS Compte
    FROM rIndividus
    GROUP BY "E"
    UNION
    SELECT "-" AS Individu, Sum(Len([Individus])-Len(Replace([Individus],[Individu],""))) AS Compte
    FROM rIndividus
    GROUP BY "-"

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 134
    Points : 53
    Points
    53
    Par défaut Réponse Galoir
    Bonjour Galoir,

    Merci pour ces pistes, mais à dire vrai, j'ai plus de 800 entrées et ne pourrai donc pas les adapter au Select que vous proposez. JE penserais alors à une corde, mais est-ce bien possible en Requête ???
    Du reste, la 1è requête est erronée puisque j'obtiens des A-----, d'autant que je peux avoir (cas non présenté dans l'exemple) des ---A-- : les deux doivent entrer dans un même et unique compte.

    Cordialement,
    Bk

  4. #4
    Invité
    Invité(e)
    Par défaut
    Si tu parles du nombre de ligne dans la table par le mot "entrée", ma proposition fonctionne avec n'importe quel nombre de lignes dans la table : 800, 1000 , 10 000,...
    As-tu au moins testé ?

    C'est quoi une corde ?

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 134
    Points : 53
    Points
    53
    Par défaut Réponse Galoir
    Oui, Galoir,

    Bien sûr que j'ai testé sinon je ne serais pas revenu en ces termes vers vous... Je ne reviens au même titre jamais publier sans avoir fait le moindre test.
    Je puis d'ailleurs indiquer que le calcul ne convient pas non plus puisque je me retrouve parfois pour un individu indiqué 9 fois dans ma table avec le double de lignes totales de la cette même table. Donc il y a un problème de compte.
    Quand je parle de 800, je ne cite pas un nom 'individus, mais le nombre approximatif d'entrées différentes possibles pour le critère "Individu".


    Cordialement,
    Bk

  6. #6
    Invité
    Invité(e)
    Par défaut
    Dans ton 1er post, seulement 6 individus et maintenant 800...
    Si le problème est mal exprimé, ça me parait difficile d'y répondre !

    Merci de me dire si avec l'exemple du 1er post ça fonctionne ou pas (a/b/c/d/e) car j'ai une solution pour 800 mais ça dépend de ce résultat
    J'ai testé avec les données de ton post n°1 et ça fonctionne chez moi : un champ contient soit un individu soit rien (NULL)

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 134
    Points : 53
    Points
    53
    Par défaut Réponse Galoir
    Galoir,

    Il me semblait que la simplicité des données et de la table permettait d'envisager qu'il s'agissait-là d'un exemple. Si ce n'est le cas, c'est donc une erreur de jugement-préjugé de ma part. Je ne suis pas parfait, la preuve par l'existence de ce topic.
    Du reste, oui, le nombre d'individus est actuellement d'environ 800 entrées, et pleinement extensifs. Le nombre de colonne en revanche ne l'est pas, il restera toujours à 6.
    En l'état, sache qu'il n'y a pas de NULL, je dois nécessairement avoir un tiret "-" si aucun individu n'est indiqué.
    Enfin, pour la réponse au modèle, en ayant repris la table d'exemple comme toi : non, cela ne fonctionne pas à l'étape finale de compte. J'obtiens partout le total de 6. Et à l'étape antérieure, 1e requête, je repère déjà ce que les tirets sont une erreur : vous menez une concaténation qui n'aide visiblement pas encore.


    Cordialement,
    Bk

  8. #8
    Invité
    Invité(e)
    Par défaut
    pour gagner du temps peux-tu mettre un extrait de la table (50 lignes par exemple) dans une base Access en PJ
    merci

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 134
    Points : 53
    Points
    53
    Par défaut Réponse Galoir
    Galoir,

    Hélas, si je l'avais pu, je l'aurais bien évidemment spontanément et initialement fait. Il s'agit de donner confidentielles que je ne peux publier.
    Cela ne change en rien la donne, me semble-t-il.


    Cordialement,
    Bk

  10. #10
    Invité
    Invité(e)
    Par défaut
    Bon, voilà une solution pour gérer les 800 entrées :
    1) Créer une table tIndividu avec une seule colonne nommée "Individu" de type TEXTE et activer la clef primaire sur cette colonne pour éviter les doublons
    2) Enregistrer et Fermer la table créée
    3) on va peupler une fois pour toute cette table avec le nom des individus à partir de votre table nommée "Table" grâce à la fonction VBA suivante :
    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
     
    Public Function PeupleTableIndividu()
    On Error GoTo MyErr
    Const cMaTable As String = "Table", cVide As String = "-"
    Dim Db As DAO.Database, RRs As DAO.Recordset, Wrs As DAO.Recordset, s As String, a() As Variant, v As Variant, i As Long
    a = Array("IndividuS1", "IndividuS2", "IndividuS3", "IndividuT1", "IndividuT2", "IndividuT3")
    Set Db = CurrentDb
    Set RRs = Db.OpenRecordset(cMaTable, dbOpenSnapshot)
    Set Wrs = Db.OpenRecordset("tIndividu", dbOpenDynaset)
     
    With RRs
    While Not .EOF
        For Each v In a
            If Nz(.Fields(v), cVide) <> cVide Then
                s = .Fields(v)
                Wrs.FindFirst "Individu=""" & s & """"
                If Wrs.NoMatch Then
                    Wrs.AddNew
                    Wrs!Individu = s
                    Wrs.Update
                    i = i + 1
                End If
            End If
        Next v
        .MoveNext
    Wend
    End With
    'Ajoute cas vide (-)
    Wrs.AddNew
    Wrs!Individu = cVide
    Wrs.Update
    MsgBox i & " individu(s) unique(s) ajouté(s) à la table tIndividu", vbInformation
     
    fin:
    RRs.Close
    Wrs.Close
    Set RRs = Nothing
    Set Wrs = Nothing
    Set Db = Nothing
    Exit Function
     
    MyErr:
        MsgBox "Erreur n°" & Err.Number & vbCrLf & "Description : " & Err.Description, vbCritical, "PeupleTableIndividu()"
        Resume fin
    End Function
    Mettre le curseur dans cette fonction et appuyer sur F5 dans l'editeur VBA pour la démarrer, un message doit s'afficher à la fin avec le nombre d'individus uniques

    4) On concatène les 6 colonnes en une en les séparant par "|" dans cette requête nommée "rIndividus". L'enregistrer et la fermer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT s&[IndividuS1]&s&s&[IndividuS2]&s&s&[IndividuS3]&s&s&[IndividuT1]&s&s&[IndividuT2]&s&s&[IndividuT3]&s AS Individus, "|" AS S
    FROM [Table]
    5) La requête finale qui utilise la table créée tIndividus et la requête précédente :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT T.Individu, Sum((Len([Individus])-Len(Replace([Individus],s & [Individu] & s,"")))/Len(s & [Individu] & s)) AS Compte
    FROM tindividu AS T, rIndividus AS R
    GROUP BY t.Individu
    HAVING (((Sum((Len([Individus])-Len(Replace([Individus],[s] & [Individu] & [s],"")))/Len([s] & [Individu] & [s])))>0));
    Chez moi ça fonctionne, le problème qui peut intervenir est que la longueur de la concaténation soit trop grande...

  11. #11
    Invité
    Invité(e)
    Par défaut
    Re bonjour,

    j'ai trouvé une solution plus simple :
    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 r.Individu, Count(r.Individu) AS CompteIndividu
    FROM (
    SELECT IndividuS1 as Individu
    FROM [Table]
    UNION all
    SELECT IndividuS2
    FROM [Table]
    UNION all
    SELECT IndividuS3
    FROM [Table]
    UNION all
    SELECT IndividuT1
    FROM [Table]
    UNION all
    SELECT IndividuT2
    FROM [Table]
    UNION ALL SELECT IndividuT3
    FROM [Table]
    ) As r
    GROUP BY r.Individu;

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 134
    Points : 53
    Points
    53
    Par défaut Réponse Galoir
    Bonjour Galoir,

    Merci beaucoup, nous avons résolu la question. Je me connectais pour indiquer avoir réussi à rassembler les 2 requêtes et les rendre justes... et je découvre que vous avez eu exactement la même idée! J'utilise plutôt de mon côté des Count (visiblement inutiles) à chaque ligne, puis un SUM total à la place de votre Count mais cela revient au même.
    Bravo !


    Cordialement,
    Bk

  13. #13
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Désolé pour la 1ère solution proposée, j'étais un peu fatigué à 2h du mat ...

    Bonne continuation

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

Discussions similaires

  1. Champs identiques avec valeur différente where dans une même table
    Par Cyrus59 dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 17/11/2014, 16h56
  2. Réponses: 4
    Dernier message: 22/04/2014, 13h11
  3. Réponses: 7
    Dernier message: 18/06/2012, 11h30
  4. Deux champs identiques dans la même table
    Par amne26 dans le forum Modélisation
    Réponses: 2
    Dernier message: 22/09/2008, 20h29
  5. [SQL] Somme de 2 colonnes dans une même table
    Par Cyrilange dans le forum Langage SQL
    Réponses: 6
    Dernier message: 11/04/2005, 08h32

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