Précédent   Forum des professionnels en informatique > Bases de données > MySQL > Requêtes
Requêtes Forum d'entraide sur les requêtes MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 10/03/2011, 18h39   #1
Candidat au titre de Membre du Club
 
Inscription : mai 2005
Messages : 16
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 16
Points : 13
Points : 13
Par défaut requeter 2 fois le meme champ sous differentes conditions

Bonjour à tous,

Désolé si le titre n'est pas très évocateur mais je voudrais savoir comment procéder pour requêter 2 fois sur le même champ mais avec 2 conditions différentes (where clause).

Je m'explique, je souhaite comptabiliser un champ (smallint(5)unsigned pouvant être NULL) pour toute mes données, puis recomptabiliser le même champ mais que pour ceux étant différent de 0 (pour les NULL ?). Le but, afin de faire un pourcentage (pour mes données la prévalence). Le tout dans une seule requête devant être générée sur une page php

Sans oublier que les COUNT(champ) se trouve sur une autre table par rapport au champ auquel je fais un GROUP BY.

Voici mon essais qui me renvoie une seule ligne (donc le GROUP BY ne marche pas avec mes sous requête, mais qu'en je les enlève c'est ok).

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
SELECT porteur.code AS porteur ,
COUNT(DISTINCT moustique.nom) AS N,
AVG(tbl1.chp1) AS Mean,
tbl2.chp2 AS nbpositif,
tbl1.chp1 AS nbtotal,
tbl2.chp2 * '100' / tbl1.chp1 AS Prevalence
FROM porteur
INNER JOIN moustique ON moustique.porteur_idporteur = porteur.idporteur
INNER JOIN 
(SELECT COUNT(midgut.chargeoocystique) AS chp1 , midgut.moustique_idmoustique
FROM midgut
) AS tbl1
ON moustique.idmoustique = tbl1.moustique_idmoustique
 
INNER JOIN
(SELECT COUNT(midgut.chargeoocystique) AS chp2, midgut.moustique_idmoustique 
FROM midgut 
WHERE midgut.chargeoocystique > '0'
) AS tbl2 
ON moustique.idmoustique = tbl2.moustique_idmoustique
 
GROUP BY porteur.code
Ma table de départ est PORTEUR, puis je recherche mes données (count à faire) sur la table midgut mais avant tout je dois passer par la table moustique (où j'en ai profité pour mettre le nombre de moustique par porteur). Sans oublier que je réalise un AVG (moyenne) sur le meme champ où je souhaite faire 2 COUNT. Pour info, lorsque ce champ = 0 cela veut dire non infecté, si >0 c'est infecté (puis les valeur c'est selon l'infestation)


table : porteur --> moustique --> midgut (ayant le champ d'intérêt)
lukeabate est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/03/2011, 10h22   #2
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 995
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 10 995
Points : 18 253
Points : 18 253
Envoyer un message via MSN à CinePhil
J'ai reformaté ta requête pour la lisibilité :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SELECT porteur.code AS porteur,
    COUNT(DISTINCT moustique.nom) AS N,
    AVG(tbl1.chp1) AS Mean,
    tbl2.chp2 AS nbpositif,
    tbl1.chp1 AS nbtotal,
    tbl2.chp2 * '100' / tbl1.chp1 AS Prevalence
FROM porteur
INNER JOIN moustique ON moustique.porteur_idporteur = porteur.idporteur
    INNER JOIN 
    (
        SELECT COUNT(midgut.chargeoocystique) AS chp1 , midgut.moustique_idmoustique
        FROM midgut
    ) AS tbl1 ON moustique.idmoustique = tbl1.moustique_idmoustique
    INNER JOIN
    (
        SELECT COUNT(midgut.chargeoocystique) AS chp2, midgut.moustique_idmoustique 
        FROM midgut 
        WHERE midgut.chargeoocystique > '0'
    ) AS tbl2 ON moustique.idmoustique = tbl2.moustique_idmoustique
GROUP BY porteur.code
C'est une horreur !
1) Toutes les colonnes du SELECT ne faisant pas l'objet d'une fonction de regroupement doivent se trouver dans le GROUP BY sinon celles qui manquent afficheront des valeurs aléatoires !
Ceci s'applique à la requête principale et aux sous-requêtes !

2) Pas besoin d'apostrophes autour des valeurs numériques !


Quant à ton besoin, il est incompréhensible !

Quand des NULL t'embêtent dans un comptage ou un affichage, utilise COALESCE.
Si tu veux compter une colonne selon plusieurs critères, utilise SUM et CASE plutôt que COUNT, comme je l'ai expliqué par exemple dans ce message.

Reviens avec un besoin clair, une description complète des tables à utiliser, un petit jeu de données et le résultat attendu, ce sera plus facile de t'aider.
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/03/2011, 11h29   #3
Candidat au titre de Membre du Club
 
Inscription : mai 2005
Messages : 16
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 16
Points : 13
Points : 13
bonjour et merci pour ta réponse,

plus généralement mon besoin c'est de retirer des valeurs sur un même champ.
par exemple, si le champ contient des valeurs comprises entre 0 et 10, j'aimerais retirer le nombre des données présentant le chiffre 0, idem pour 1, 2 ... voir ceux étant >5 et puis faire des choses comme pourcentage avec les valeurs obtenues ...

pour CASE je vais voir de suite ce que c'est

pour le GROUP BY, je souhaite dans ma requete, n'obtenir que le même nombre de ligne qu'il y a de porteur, en revenant sur ma requête foireuse, qu'en je teste sur mes données (2 porteurs) cela me renvoie 1 porteur (donc 1 ligne), et les COUNT sont générés sur les données des 2 porteurs confondus (du moins il semble car valeurs correspondes).

ex mes données :

porteur / moustique / chargeoocystique (nb)
001 / id1 / 25
001 / id2 / 15
001 / id3 / 0
001 / id4 / 21
002 / id5 / 26

souhaite recevoir avec la requete :

pour le porteur 001 il y a 3 non nul et 1 nul sur 4 au total
pour le porteur 002 il y a 1 non nul et 0 nul sur 1 au total

ce que je recois avec la requete bacale :
pour le porteur 001 il y a 4 non nul et 1 nul sur 5 au total

edit : par non nul je veux dire différent à 0
lukeabate est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/03/2011, 12h10   #4
Candidat au titre de Membre du Club
 
Inscription : mai 2005
Messages : 16
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 16
Points : 13
Points : 13
rebonjour,
j'ai fait comme dans l'exemple que tu m'as passé (SUM et CASE) c'est plutôt simple a comprendre, toutefois j'ai l'erreur 'FUNCTION nombase.SUM does not exist'
sinon le nouveau code (garde count pour nbtotal car sans condition)
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
SELECT 
	porteur.code AS 'code porteur', 
	COUNT(DISTINCT moustique.nom) AS N, 
	AVG(midgut.chargeoocystique) AS Mean, 
	SUM (
		CASE
			WHEN midgut.chargeoocystique > 0 THEN 1
			ELSE 0
		END
	) AS nbpositif,
	COUNT(midgut.chargeoocystique) AS nbtotal
FROM porteur 
	INNER JOIN moustique ON moustique.porteur_idporteur = porteur.idporteur
	INNER JOIN midgut ON moustique.idmoustique = midgut.moustique_idmoustique
GROUP BY porteur.code
EDIT : erreur de ma part, la fonction SUM marche, c'est juste que j'avais mis un espace entre SUM et la parenthèse d'ouverture

Pour pourcentage :
Code :
1
2
3
4
5
6
	SUM(
		CASE
			WHEN midgut.chargeoocystique > 0 THEN 1
			ELSE 0
		END
	) * 100 / COUNT(midgut.chargeoocystique) AS Prev
La requête marche, encore merci pour l'aiguillage
lukeabate est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 18h44.


 
 
 
 
Partenaires

Hébergement Web