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 :

Quelles clause pour compter le nombre occurrences dans une colonne à partir d'une ligne


Sujet :

Langage SQL

  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    540
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2009
    Messages : 540
    Points : 532
    Points
    532
    Par défaut Quelles clause pour compter le nombre occurrences dans une colonne à partir d'une ligne
    Bonjour,

    Désolé si le titre n'est pas clair...
    Admettons une table toute simple : ID, LIBELLE, PROVENANCE. Dans cette table, je souhaite extraire l'id, le libellé et le nombre de ligne où provenance = id.

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    1, toto, -1
    2, titi, -1,
    3, tutu, 1
    4, tata, 1
    5, toutou, 2
    Je souhaite obtenir quelques chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    1, toto, 2
    2, titi, 1,
    3, tutu, 0
    4, tata, 0
    5, toutou, 0
    Dans mon cas précis, j'ai beaucoup plus de colonnes qui sont déjà issues d'une jointure de plusieurs tables.

    J'ai essayé de faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT id, libelle, droite.nb
    FROM
       (SELECT id, libelle, provenance FROM Table) AS gauche,
       (SELECT COUNT(*) AS nb, provenance FROM Table GROUP BY provenance) AS droite
    Initialement, je le faisais en 2 requête mais le but serait de trier par nombre de provenance

    Merci d'avance pour votre aide

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 874
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 874
    Points : 53 048
    Points
    53 048
    Billets dans le blog
    6
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT id, libelle, droite.nb,  COUNT(*) OVER(PARTITION BY provenance) AS nb
    FROM ...
    A +

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 243
    Points : 12 874
    Points
    12 874
    Par défaut
    Bonjour,
    Je dirai un truc du genre:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select id,libelle,sum(case when provenance = id then 1 else 0 end)
    from latable
    group by id,libelle

    Tatayo.

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Une solution scalaire, acceptable avec un index sur provenance et pas trop de données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      select id, libelle
           , (select count(*) from MaTable as t2 where t2.provenance = t1.id) as nb
        from MaTable as t1
    order by id asc;
    Une solution avec jointure, préférable si vous n'avez pas d'index sur provenance ou beaucoup de données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    with cte_agg (provenance, nb) as
    (
      select provenance, COUNT(*)
        from MaTable
    group by provenance
    )
        select t1.id, t1.libelle, coalesce(t2.nb, 0) as nb
          from MaTable as t1
     left join cte_agg as t2 on t2.provenance = t1.id
      order by t1.id asc;

  5. #5
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    540
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2009
    Messages : 540
    Points : 532
    Points
    532
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT id, libelle, droite.nb,  COUNT(*) OVER(PARTITION BY provenance) AS nb
    FROM ...
    A +
    Merci. Mais...

    Ca me produit :

    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
    1, toto, 0
    1, toto, 1
    1, toto, 2
    2, titi, 0,
    2, titi, 1,
    2, titi, 2,
    3, tutu, 0
    3, tutu, 1
    3, tutu, 0
    4, tata, 0
    4, tata, 1
    4, tata, 2
    5, toutou, 0
    5, toutou, 1
    5, toutou, 2
    au lieu de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    1, toto, 2
    2, titi, 1,
    3, tutu, 0
    4, tata, 0
    5, toutou, 0

  6. #6
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    540
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2009
    Messages : 540
    Points : 532
    Points
    532
    Par défaut
    Citation Envoyé par tatayo Voir le message
    Bonjour,
    Je dirai un truc du genre:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select id,libelle,sum(case when provenance = id then 1 else 0 end)
    from latable
    group by id,libelle

    Tatayo.
    Merci. Mais...
    Je n'ai pas seulement 1 ou 0...

  7. #7
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    540
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2009
    Messages : 540
    Points : 532
    Points
    532
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Une solution scalaire, acceptable avec un index sur provenance et pas trop de données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      select id, libelle
           , (select count(*) from MaTable as t2 where t2.provenance = t1.id) as nb
        from MaTable as t1
    order by id asc;

    Je vais me contenter de ça. Merci beaucoup

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 243
    Points : 12 874
    Points
    12 874
    Par défaut
    Citation Envoyé par oneagaindoguys Voir le message
    Merci. Mais...
    Je n'ai pas seulement 1 ou 0...
    Oui, mais... les 1 et 0 permettent juste de compter les lignes "qui vont bien".
    Je regroupe les lignes sur l'Id et le libelle, et je fais la somme de (si provenance = id alors 1 sinon 0).
    Pour moi cette requête répond à la question posée.
    Il suffit d'enlever le SUM et le GROUP BY, de lire le résultat et de faire le calcul à la main pour s'en convaincre.

    Tatayo.

  9. #9
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Citation Envoyé par tatayo Voir le message
    Oui, mais... les 1 et 0 permettent juste de compter les lignes "qui vont bien".
    Mais uniquement sur la ligne en cours, hors le besoin est bien d'avoir des informations par rapport à toute la table.

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 243
    Points : 12 874
    Points
    12 874
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Mais uniquement sur la ligne en cours, hors le besoin est bien d'avoir des informations par rapport à toute la table.
    Autant pour moi, je viens de me rendre compte que j'avais compris la demande de travers

    Tatayo.

  11. #11
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    540
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2009
    Messages : 540
    Points : 532
    Points
    532
    Par défaut
    Pas de souci
    Merci pour vos réponses en tout cas !

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 12/03/2015, 11h46
  2. [Toutes versions] Besoin d'un code pour vérifier l'existence d'une chaine à partir d'une colonne dans une autre
    Par Chedy Smida dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 20/02/2015, 17h05
  3. Réponses: 3
    Dernier message: 06/07/2012, 16h01
  4. Solution pour la creation de contacts dans l'AD à partir d'une vue
    Par smorin007 dans le forum Développement
    Réponses: 0
    Dernier message: 01/09/2008, 12h00
  5. Réponses: 2
    Dernier message: 31/01/2008, 17h58

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