PHP|Débutant :: Forums

Advertisement

Besoin d'aide ? N'hésitez pas, mais respectez les règles

Vous n'êtes pas identifié(e).

#1 19-07-2010 21:11:54

moijhd
Membre
Inscription : 13-06-2009
Messages : 167

Réduction de la requête

Bonjour,

Je n'arrive pas à écrire tout en SQL la requête suivante. Le but est d'obtenir une liste d'élèves : soit celle des cotisants, soit celle des non-cotisants, soit celle des deux.

[code php]
    public function RechercheParApproche($NomEleve, $PrenomEleve, $AnneeEleve, $CotisantEleve){
            if($CotisantEleve == -1){
            $SqlCotisation = "";
            $Cotisant = "
                (
                    SELECT
                        CASE
                            WHEN COUNT(*) >= 1
                            THEN true
                            ELSE false
                        END as nombre
                    FROM
                        cotisations
                    WHERE
                        CASE WHEN CURDATE() < STR_TO_DATE(CONCAT(YEAR(CURDATE()),'0630'),'%Y%m%d')
                            THEN cotisations.date_achat BETWEEN
                                    STR_TO_DATE(CONCAT(YEAR(CURDATE())-1,'0701'),'%Y%m%d') AND
                                    STR_TO_DATE(CONCAT(YEAR(CURDATE()),'0701'),'%Y%m%d')
                            ELSE cotisations.date_achat BETWEEN
                                    STR_TO_DATE(CONCAT(YEAR(CURDATE()),'0701'),'%Y%m%d') AND
                                    STR_TO_DATE(CONCAT(YEAR(CURDATE())+1,'0701'),'%Y%m%d')
                        END    AND
                        cotisations.id_eleve = eleves.id       
                )       
            ";
        }
        else{
            if($CotisantEleve == 'true'){
                $SqlCotisation = "";
                $Cotisant = 'true';
            }
            else{
                $SqlCotisation = " NOT ";
                $Cotisant = 'false';
            }
            $SqlCotisation .= "
                EXISTS (
                        SELECT
                            id
                        FROM
                            cotisations
                        WHERE
                            CASE WHEN CURDATE() < STR_TO_DATE(CONCAT(YEAR(CURDATE()),'0630'),'%Y%m%d')
                                THEN cotisations.date_achat BETWEEN
                                        STR_TO_DATE(CONCAT(YEAR(CURDATE())-1,'0701'),'%Y%m%d') AND
                                        STR_TO_DATE(CONCAT(YEAR(CURDATE()),'0701'),'%Y%m%d')
                                ELSE cotisations.date_achat BETWEEN
                                        STR_TO_DATE(CONCAT(YEAR(CURDATE()),'0701'),'%Y%m%d') AND
                                        STR_TO_DATE(CONCAT(YEAR(CURDATE())+1,'0701'),'%Y%m%d')
                            END    AND
                            cotisations.id_eleve = eleves.id       
                    ) AND
            ";
        }
        $Sql = "
            SELECT
                eleves.*,
                $Cotisant AS cotisant       
            FROM
                eleves
            WHERE
                $SqlCotisation
                eleves.nom LIKE '%$NomEleve%' AND
                eleves.prenom LIKE '%$PrenomEleve%' AND
                eleves.annee LIKE '%$AnneeEleve%'
            ORDER BY
                eleves.nom ASC,
                eleves.prenom ASC,
                eleves.id ASC
        ";

    }


[/code]

Sous une autre forme (le WHERE et ORDER BY en moins), je voudrais faire une seule requête à la place des trois suivantes ($CotisantEleve étant alors un paramêtre ?) :

[code mysql]
SELECT
                eleves.*,
                true AS cotisant       
            FROM
                eleves
            WHERE
               
                EXISTS (
                        SELECT
                            id
                        FROM
                            cotisations
                        WHERE
                            CASE WHEN CURDATE() < STR_TO_DATE(CONCAT(YEAR(CURDATE()),'0630'),'%Y%m%d')
                                THEN cotisations.date_achat BETWEEN
                                        STR_TO_DATE(CONCAT(YEAR(CURDATE())-1,'0701'),'%Y%m%d') AND
                                        STR_TO_DATE(CONCAT(YEAR(CURDATE()),'0701'),'%Y%m%d')
                                ELSE cotisations.date_achat BETWEEN
                                        STR_TO_DATE(CONCAT(YEAR(CURDATE()),'0701'),'%Y%m%d') AND
                                        STR_TO_DATE(CONCAT(YEAR(CURDATE())+1,'0701'),'%Y%m%d')
                            END    AND
                            cotisations.id_eleve = eleves.id       
                    )

[/code]

[code mysql]
SELECT
                eleves.*,
                false AS cotisant       
            FROM
                eleves
            WHERE
                 NOT
                EXISTS (
                        SELECT
                            id
                        FROM
                            cotisations
                        WHERE
                            CASE WHEN CURDATE() < STR_TO_DATE(CONCAT(YEAR(CURDATE()),'0630'),'%Y%m%d')
                                THEN cotisations.date_achat BETWEEN
                                        STR_TO_DATE(CONCAT(YEAR(CURDATE())-1,'0701'),'%Y%m%d') AND
                                        STR_TO_DATE(CONCAT(YEAR(CURDATE()),'0701'),'%Y%m%d')
                                ELSE cotisations.date_achat BETWEEN
                                        STR_TO_DATE(CONCAT(YEAR(CURDATE()),'0701'),'%Y%m%d') AND
                                        STR_TO_DATE(CONCAT(YEAR(CURDATE())+1,'0701'),'%Y%m%d')
                            END    AND
                            cotisations.id_eleve = eleves.id       
                    )


[/code]

[code mysql]
SELECT
                eleves.*,
               
                (
                    SELECT
                        CASE
                            WHEN COUNT(*) >= 1
                            THEN true
                            ELSE false
                        END as nombre
                    FROM
                        cotisations
                    WHERE
                        CASE WHEN CURDATE() < STR_TO_DATE(CONCAT(YEAR(CURDATE()),'0630'),'%Y%m%d')
                            THEN cotisations.date_achat BETWEEN
                                    STR_TO_DATE(CONCAT(YEAR(CURDATE())-1,'0701'),'%Y%m%d') AND
                                    STR_TO_DATE(CONCAT(YEAR(CURDATE()),'0701'),'%Y%m%d')
                            ELSE cotisations.date_achat BETWEEN
                                    STR_TO_DATE(CONCAT(YEAR(CURDATE()),'0701'),'%Y%m%d') AND
                                    STR_TO_DATE(CONCAT(YEAR(CURDATE())+1,'0701'),'%Y%m%d')
                        END    AND
                        cotisations.id_eleve = eleves.id       
                )       
             AS cotisant       
            FROM
                eleves

[/code]

Dernière modification par moijhd (19-07-2010 21:22:42)

Hors ligne

#2 19-07-2010 23:25:33

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Réduction de la requête

Bonjour,

Si j'ai bien compris ton problème, tu as la table élèves contenant tous les élèves, la table cotisations contenant tous les élèves ayant cotisés, et tous ceux qui n'ont pas cotisé, ne sont pas présent dans la table cotisations. A partir de là, tu souhaites établir "une liste d'élèves : soit celle des cotisants, soit celle des non-cotisants, soit celle des deux."


Si c'est bien ça, je te suggère de t'inspirer de la méthode que j'ai exposé dans ce post : Post forum PHPdébutants.

Cordialement,

Dernière modification par Jc (19-07-2010 23:27:01)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#3 20-07-2010 10:12:16

moijhd
Membre
Inscription : 13-06-2009
Messages : 167

Re : Réduction de la requête

J'ai parcouru le lien. C'est un peu dense...J'ai noté la redondance de l'utilisation d'UNION. Je ne sais pas si c'est ce sur quoi je dois me focaliser ?

Hors ligne

#4 20-07-2010 22:01:08

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Réduction de la requête

Bonsoir,

Tu ne m'a pas répondu quand à savoir si l'exposé en résumé de ton problème que j'ai fait à mon post précédent est correct.

Si c'est le cas donc, c'est en effet la méthode simple à utiliser (surtout si tu souhaites faire un tri sur ideleve=x mais elle a l'avantage de monitorer l'ensemble des élèves) car elle te permet de structurer tes résulats comme suit :

colonne 1 : id eleve
colonne 2 : cotisant (true/false)
colonne 4 : l'info que tu veux (par ex: montant de renouvellement de la cotisation / ou montant de souscription de la cotisation et ce en fonction du statut de cotisant ou non cotisant)
colonne x: l'info que tu veux

Dans le post tu as toutes les règles à utiliser pour que ta requête union fonctionne.

Si tu as besoin d'un coup de main fait moi signe. Mais si c'est le cas, faudra que tu m'expliques bien comment sont structurées tes tables et l'utilisation que tu en fait (pour les champs utilisés dans ta requête), sinon difficile de t'aider dans ta requête union.

++

Dernière modification par Jc (20-07-2010 22:14:17)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

Pied de page des forums