Partage
  • Partager sur Facebook
  • Partager sur Twitter

tout mettre en une seule requete

    23 avril 2011 à 21:56:24

    Bonjour à tous.
    Je désire créer des statistiques à partir de mes données, voici les quatres grosses statistisques :
    nombre de bien,
    nombre de biens loués,
    % location effective/location proposée
    % reservation / location proposée
    Somme totale d'argent gagnée

    voici les champs de ma table :
    --
    -- Structure de la table 'personne'
    --
    
    DROP TABLE IF EXISTS personne;
    CREATE TABLE IF NOT EXISTS personne (
      id int(11) NOT NULL AUTO_INCREMENT,
      civilite varchar(4) NOT NULL,
      nom varchar(50) NOT NULL,
      prenom varchar(50) NOT NULL,
      date_naissance date DEFAULT NULL,
      telephone varchar(20) DEFAULT NULL,
      mobile varchar(20) DEFAULT NULL,
      mail varchar(50) NOT NULL,
      valide tinyint(1) NOT NULL,
      login varchar(20) NOT NULL,
      mdp varchar(255) NOT NULL,
      ref_langue int(11) NOT NULL,
      ref_categorie int(11) NOT NULL,
      ref_adresse int(11) DEFAULT NULL,
      PRIMARY KEY (id),
      UNIQUE KEY `unic_login`(login),
      FOREIGN KEY (ref_langue) REFERENCES langue (id_langue),
      FOREIGN KEY (ref_categorie) REFERENCES categorie (id_categorie),
      FOREIGN KEY (ref_adresse) REFERENCES adresse (id_adresse)
    ) ENGINE=InnoDB;
    
    
    -- --------------------------------------------------------
    
    --
    -- Structure de la table 'bien'
    --
    
    DROP TABLE IF EXISTS bien;
    CREATE TABLE IF NOT EXISTS bien (
      id_bien int(11) NOT NULL AUTO_INCREMENT,
      nom varchar(50) NOT NULL,
      capacite int(11) NOT NULL,
      categorie varchar(50) NOT NULL,
      ref_adresse int(11) NOT NULL,
      ref_proprio int(11) NOT NULL,
      ref_intermediaire int(11) NOT NULL,
      PRIMARY KEY (id_bien),
      FOREIGN KEY (ref_proprio) REFERENCES personne (id),
      FOREIGN KEY (ref_adresse) REFERENCES adresse (id_adresse),
    
      FOREIGN KEY (ref_intermediaire) REFERENCES personne (id)
    
    =======
      FOREIGN KEY (ref_intermediaire) REFERENCES personne (id)
    
    ) ENGINE=InnoDB;
    
    
    DROP TABLE IF EXISTS location;
    CREATE TABLE IF NOT EXISTS location (
      id_location int(11) NOT NULL AUTO_INCREMENT,
      date_debut date NOT NULL,
      duree int(11) NOT NULL,
      prix int(11) NOT NULL,
      promo int(11) DEFAULT NULL,
      etat varchar(50) NOT NULL,
      num_contrat varchar(30) DEFAULT NULL,
      ref_bien int(11) NOT NULL,
      ref_personne int(11) DEFAULT NULL,
      PRIMARY KEY (id_location),
      FOREIGN KEY (ref_personne) REFERENCES personne (id),
      FOREIGN KEY (ref_bien) REFERENCES bien (id_bien)
    ) ENGINE=InnoDB;
    



    Pour l'instant, pour chaque chose, je fais une requete. Le problème c'est qu'en matière de traitement on s'y perd assez vite
    voici les requetes :
    -nombre de biens loues + prix
    SELECT COUNT(loc.id_location) AS nbLoues, SUM(loc.prix) AS C_A 
    , proprio.nom, proprio.prenom
    FROM location loc
    INNER JOIN personne proprio ON proprio.id=location.ref_proprio
    WHERE loc.etat='loue'
    GROUP BY loc.ref_proprio
    


    Je me demande si je ne pourrais pas grouper cette requete avec celle qui compte le nombre de bien au total, nottemment grâce à des sous requetes?
    • Partager sur Facebook
    • Partager sur Twitter
      23 avril 2011 à 23:03:07

      Tu peux virer le "loc.etat='loue'" du WHERE, tu auras les loués et les non loués.

      Remplace COUNT(loc.id_location) qui ne sert à rien par un simple count(*) (loc.id_location n'est jamais NULL puisque tu utilises un INNER JOIN et non un LEFT JOIN) : ça te donne le total.

      sum( loc.etat='loue' ) te donne le nombre de biens loués (le bool True vaut 1... donc la somme c'est le nombre de lignes où tu as True...)

      pour les autres, je ne sais pas trop comment tu as encodé l'info...
      • Partager sur Facebook
      • Partager sur Twitter
        24 avril 2011 à 9:05:56

        ça donnerait ça :? (je viens de voir que j'avais une erreur de toute façon)
        SELECT COUNT(*) AS nbLoc,sum( loc.etat='loue' )AS nbLoues, SUM(loc.prix) AS C_A , SUM(loc.etat='reserve') AS nbReserve
        , proprio.nom, proprio.prenom
        FROM location loc
        INNER JOIN bien b ON b.id_bien=loc.ref_bien
        INNER JOIN personne proprio ON proprio.id=b.ref_proprio
        
        GROUP BY b.ref_proprio
        


        La syntaxe parait bonne, cependant, il y a un problème avec la colonne C_A du fait que WHERE loc.etat='loue' a été enlevé. En effet, il me donne la somme de tous les prix, or moi, je veux la somme des prix où l'état vaut 'loue'.

        Encore merci de ton aide, tu es vraiment le gourou du SQL.
        • Partager sur Facebook
        • Partager sur Twitter
          24 avril 2011 à 10:20:14

          LOL

          oui effectivement la somme des prix va être foireuse.

          Tu peux mettre sum( IF(loc.etat='loue', loc.prix, 0)) par exemple

          Le faire en une seule requête c'est bien parce que tu scan 1 fois les tables mais ça peut devenir abscons...
          • Partager sur Facebook
          • Partager sur Twitter
            24 avril 2011 à 11:12:30

            Oui, en fait, je voulais vraiment savoir l'allure qu'avait la requete pour éviter de surcharger en scan et surtout en fetch. En plus ça évite les doublons et leur traitement.

            En tout cas ça marche ! En plus j'ai tout compris !!
            • Partager sur Facebook
            • Partager sur Twitter

            tout mettre en une seule requete

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown