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

MS SQL Server Discussion :

Comptage d'un table donnée dans une "cellule"


Sujet :

MS SQL Server

  1. #1
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut Comptage d'un table donnée dans une "cellule"
    Bonjour à tous,
    Désolé pour le titre pas du tout clair, mais je ne vois vraiment pas comment exprimer ce que je recherche en 2/3 mots.

    Je me doute bien de la réponse, mais j'aimerai confirmation.
    Sous SQL Server 2008 R2, je fais un select [...] FROM [... avec tout plein de jointures]

    Ca me donne un résultat du genre :
    |colonne1 |colonne2 |.....|NomDeTable     |
    +---------+---------+-----+---------------+
    |bla bla  +bla bla  +.....+dbo.AutreTable1|
    +---------+---------+-----+---------------+
    |bla bla  +bla bla  +.....+dbo.AutreTable2|
    
    J'aimerai inclure, dans la même requête, une colonne qui ramènerai le nombre de lignes présentes dans les tables données dans la colonne "NomDeTable", en gros :
    |colonne1 |colonne2 |.....|NomDeTable     |NbLignes|
    +---------+---------+-----+---------------+--------|
    |bla bla  +bla bla  +.....+dbo.AutreTable1|12      |
    +---------+---------+-----+---------------+--------|
    |bla bla  +bla bla  +.....+dbo.AutreTable2|0       |
    
    Je ne peux en aucun cas passer par un sp_execute ou je ne sais quelle autre fourberie, la requête dois être faite en une fois.
    Si ce n'est pas possible, comme je le pense, j'obtiendrai ces valeurs par code.

    Du coup je ne vois pas du tout comment je peux faire ca. Faut dire que je suis pas bien doué en SQL.

    Il y peut être moyen en faisant des jointures sur les tables système non ? Enfin, je suis pas bien fan de cette solution (a supposé que ce soit possible)

    EDIT: Ah oui, j'ai oublié de préciser un détail qui change peut être la donne. En fait je m'en fout complètement du nombre exacte d'enregistrements dans les tables, ce que je voudrais c'est savoir si il y a ou non des enregistrements, leurs nombre n'a pas d'intérêt.

  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 995
    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 995
    Billets dans le blog
    6
    Par défaut
    En utilisant les tables système, vous pouvez obtenir une bonne approximation avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT   SUM(p.rows) AS NOMBRE_LIGNE
    FROM     sys.partitions p
             INNER JOIN sys.objects O
               ON p.object_ID = O.object_id
    WHERE    p.index_id IN (0, 1)
      AND    p.object_id = OBJECT_ID('???')
    Ou ??? est le nom de votre table (avec son préfixe de schéma).

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Merci bien de la réponse, je garde ca sous le coude, je testerai lundi.
    Et sinon, quid de l'impacte sur les perfs de faire des jointures sur les tables system pour ca ?

    Je veux dire, qu'est-ce qui serait le plus performant ? faire tout en une requête via des jointures sur les tables système, ou bien exécuter la requêtes "principale", puis exécuter un count(*) sur chaque table ?
    Ca me semble bien lourd d'attaquer les tables système extrêmement volumineuses uniquement pour savoir si 3 ou 4 tables son vides ou non.

  4. #4
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Bonjour,

    Je veux dire, qu'est-ce qui serait le plus performant ? faire tout en une requête via des jointures sur les tables système, ou bien exécuter la requêtes "principale", puis exécuter un count(*) sur chaque table ?
    Ca me semble bien lourd d'attaquer les tables système extrêmement volumineuses uniquement pour savoir si 3 ou 4 tables son vides ou non.
    Dans tous les cas faire des jointures ne pose aucun problème, pourvu que vos tables soient bien indexées.

    A l'évidence rechercher le nombre de lignes d'une table dans les vues système est bien plus rapide est moins coûteux en termes de performances, que de compter toutes les lignes de chacune des tables de votre base de données.

    J'avais publié comment trouver le nombre de lignes de toutes les tables ici

    @++

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 995
    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 995
    Billets dans le blog
    6
    Par défaut
    Mais tu as oublié un SUM sur le nombre de lignes car s'il y a deux partitions tu va avoir 2 résultats !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  6. #6
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Voila qui est fort intéressant. Je pensais qu'inclure les tables système était fort couteux. Merci bien pour ces infos, Je teste ca dès que je suis de retour au boulot.

    @SQLpro: La précision est d'importance, on a effectivement fait plusieurs partitions

  7. #7
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Bien le bonjour !
    J'ai testé et ca fonctionne très bien. Cependant, une modification des specs remet tout en cause ...
    Avant j'avais besoin de savoir si la table avait ou non des lignes. Maintenant il faut savoir si elle a ou non des lignes qui correspondent à un critère.

    Petit exemple pour mieux me faire comprendre

    Le résultat de la requête :
    colonne1|colonne2|...|colonneN|Condition|TableName     |Count
    --------+--------+---+--------+---------+--------------+-----
    bla bla |bla bla |...|bla bla | 12345   |dbo.AutreTable|2
    
    Le contenu de la table dbo.AutreTable :
    col1|col2|...|colN|Condition
    ----+----+---+----+---------
    bla |bla |...|bla | 12345   
    ----+----+---+----+---------
    bla |bla |...|bla | 12345   
    ----+----+---+----+---------
    bla |bla |...|bla | 29      
    
    La requête retourne donc 2 car il y a deux lignes dans la table dbo.AutreTable qui ont la même condition.

    Cette nouvelle contrainte ne me semble pas possible via les tables systèmes. Une idée ?
    Sinon tant pis, je ferai ca par code. En tout cas merci pour la solution d'avant, ca pourra me servir ailleurs

  8. #8
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Dans ce cas vous ne pouvez plus effectivement utiliser les tables système, et vous êtes obligé d'effectuer un COUNT(*) avec un WHERE.

    Le mieux serait de stocker dans une table :
    - le nom de la table
    - le texte du filtre WHERE
    - le nombre de lignes qui vérifient le WHERE la dernière fois que la table a été scannée
    - un bit qui indique si la table a été traitée

    Ensuite il suffit de faire une boucle WHILE en utilisant sp_executeSQL pour récupérer le résultat, et procéder à l'UPDATE de cette table.

    Considérez néanmoins la taille des tables que vous traitez, car un COUNT(*) sur une colonne non indexée d'une table de plusieurs millions de lignes peut prendre du temps

    @++

  9. #9
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Bon bah j'ai traité ca par code. Je tag donc en résolut.
    C'est un sacré manque du sql je trouve de ne pas pouvoir faire des "jointures dynamiques", parce qu'en l'occurrence j'aurais trouvé ca naturel de pouvoir faire un champs calculé par une sous-requête effectuant un count sur le champs clé primaire de la table liée.

    Enfin bon, je vais pas refaire le monde des SGBD aujourd'hui, j'ai pas encore ma dose de caféine pour être assez motiver pour ca

    Merci pour toutes les réponses

  10. #10
    Expert confirmé
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Par défaut
    La requête dynamique est possible ici mais ne peut évidement pas être exécutée en une seule fois. N'hésitez pas à utiliser l'indicateur NOLOCK dans votre cas pour éviter des verrous excessifs qui pourraient porter préjudice à votre production (à moins que vous exécutiez cette requête en dehors de votre activité de production bien entendu)

    ++

  11. #11
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Je ne peux décemment pas appeler ca une requête dynamique si je dois la faire en plusieurs fois sous prétexte qu'une partie de la requête est déterminée par une ou deux valeurs de cellule.
    C'est pour ce genre de détail que je n'aime pas le sql, je me sens beaucoup trop enfermé/limité par le langage.

    Je prend note du coup de l'indicateur NOLOCK, ca peut effectivement être très utile. Merci

  12. #12
    Expert confirmé
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Par défaut
    Disons qu'il faut commencer par construire la requête avant de pouvoir l'utiliser avec un EXEC ou sp_executesql. Donc cela se fait en 2 fois

    Par curiosité et intérêt pour la discussion pourriez vous quand même nous poster le code que vous utilisez pour récupérer ces informations ? Et pourquoi vous ne pouvez pas utiliser le SQL dynamique dans votre cas ?

    ++

  13. #13
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Ca va être dur à poster ce code
    Le fait est que l'on a dev tout un ORM qui effectue énormément de traitement de mise en cache en tout genre (selon les types d'objets on ne met pas tout en cache de la même manière, il y a de la sérialisation xml, sérialisation binaire, certains objets sont mis en caches pour toute l'appli, d'autre selon le user, etc...) tout mon code est basé dessus, il faudrait que je poste l'ORM avec pour qu'il ai le moindre sens.
    Sans compter que je n'en ai tout simplement pas le droit.

    Je peux y faire appel sans trop de perte de perf dans la mesure où tous les objets dont j'ai besoins ont déjà étés mis en cache pour une raison ou une autre.

    Donc si je suis pour générer une requête, autant le faire par code compilé, c'est tout autant efficace.

    Je rappel également que les tables que je consultes sont légères en nombre de lignes, ca dépassera pas le petit millier. Le but étant de remplir une TreeList, je souhaitait avoir une requête qui remonte toutes les infos d'un coup, mais au final je requête pour avoir seulement les infos de ce qui est visible dans la treelist (donc je requête a nouveau sur ouverture d'un noeud pour avoir les infos enfants).
    C'est pas spécialement efficace, mais il s'agit d'une interface où les noeuds seront très rarement dépliés et où la rapidité n'est pas une nécessite (bon faut pas non plus que ca prenne 12 secondes pour afficher 3 noeuds ... mais on en est très loin).

  14. #14
    Membre Expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Par défaut
    pour en revenir au table système,si vous connaissez vos critères à l'avance, créer une vue indexée filtrée.

    Une fois indexée elle devrait se retrouver dans vos tables systèmes (pas testé...).


    Je rappel également que les tables que je consultes sont légères en nombre de lignes, ca dépassera pas le petit millier. Le but étant de remplir une TreeList, je souhaitait avoir une requête qui remonte toutes les infos d'un coup, mais au final je requête pour avoir seulement les infos de ce qui est visible dans la treelist (donc je requête a nouveau sur ouverture d'un noeud pour avoir les infos enfants).
    C'est pas spécialement efficace, mais il s'agit d'une interface où les noeuds seront très rarement dépliés et où la rapidité n'est pas une nécessite (bon faut pas non plus que ca prenne 12 secondes pour afficher 3 noeuds ... mais on en est très loin).
    Pourquoi ne pas mettre cela en cache également?
    Beaucoup de personne peuvent accéder à ce treelist? si oui c'est beaucoup de requêtes qui transite pour pas grand chose...

  15. #15
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Aucun intérêt de mettre ca en cache car les valeurs changes souvent. En mettant en cache, il faudrait invalider le cache a chaque fois, refaire la requête et remettre en cache.

  16. #16
    Membre Expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Par défaut
    les valeurs changes souvent
    OK

  17. #17
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Tien, ca me fait pensé que j'ai oublier de mettre le tag résolut, je fais ca de suite.
    EDIT: ah ba non en fait, je l'avais déjà fait... on voit que je suis encore super réveillé ...

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

Discussions similaires

  1. Liste de données dans une seule cellule.
    Par azure dans le forum Excel
    Réponses: 2
    Dernier message: 09/04/2008, 18h25
  2. Réponses: 4
    Dernier message: 19/09/2005, 15h59
  3. Réponses: 2
    Dernier message: 15/06/2005, 17h32

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