MySQL : regrouper efficacement les décomptes sur plusieurs colonnes au sein d'une seule table
Plusieurs requêtes ciblant la même table mais des colonnes différentes dans MySQL peuvent conduire à une récupération de données inefficace et à des résultats inexacts. Illustrons cela avec un exemple et montrons la bonne approche.
Supposons que vous deviez calculer les décomptes en fonction de divers critères dans le t_hospital
tableau :
Méthode inefficace (requêtes multiples) :
Le code suivant tente d'y parvenir en utilisant plusieurs requêtes, mais il produit des résultats incorrects pour les colonnes au-delà de la première :
<code class="language-sql">SET @start_res = 20150301; SET @finish_res= 20150501; SET @finish_check= 20150801; SET @start_check= 20150301; SET @daily_hos= 3; SELECT* from ( SELECT COUNT(DAY_IN) AS arr FROM t_hospital WHERE DAY_IN between @start_check and @finish_check and RES_DATE between @start_res and @finish_res and ID_daily_hos =@daily_hos group by DAY_IN )e, (SELECT COUNT(PAT_STATUS) AS ONG1 FROM t_hospital WHERE PAT_STATUS like '%ong%' and DAY_IN between @start_check and @finish_check and RES_DATE between @start_res and @finish_res and ID_daily_hos =@daily_hos group by DAY_IN ) a, (SELECT COUNT(PAT_STATUS) AS RTED FROM t_hospital WHERE PAT_STATUS like '%rtde%'and DAY_IN between @start_check and @finish_check and RES_DATE between @start_res and @finish_res and ID_daily_hos =@daily_hos group by DAY_IN )b, (SELECT COUNT(PAT_STATUS) AS POLI FROM t_hospital WHERE PAT_STATUS like '%pol%'and DAY_IN between @start_check and @finish_check and RES_DATE between @start_res and @finish_res and ID_daily_hos =@daily_hos group by DAY_IN )c, (SELECT COUNT(PAT_STATUS) AS para FROM t_hospital WHERE PAT_STATUS like '%para%' and DAY_IN between @start_check and @finish_check and RES_DATE between @start_res and @finish_res and ID_daily_hos =@daily_hos group by DAY_IN )d;</code>
Méthode efficace (requête unique avec agrégation conditionnelle) :
La solution optimale implique une seule requête utilisant l'agrégation conditionnelle :
<code class="language-sql">SELECT DAY_IN, COUNT(*) AS arr, SUM(IF(PAT_STATUS like '%ong%', 1, 0)) AS ONG1, SUM(IF(PAT_STATUS like '%rtde%', 1, 0)) AS RTED, SUM(IF(PAT_STATUS like '%pol%', 1, 0)) AS POL1, SUM(IF(PAT_STATUS like '%para%', 1, 0)) AS para FROM t_hospital WHERE DAY_IN between @start_check and @finish_check and RES_DATE between @start_res and @finish_res and ID_daily_hos =@daily_hos GROUP BY DAY_IN;</code>
Cette approche utilise la fonction IF()
pour compter conditionnellement les occurrences en fonction de PAT_STATUS
valeurs, et SUM()
agrège ces décomptes pour chaque DAY_IN
. Cette méthode est nettement plus efficace et fournit des résultats précis. Il évite le produit cartésien implicitement créé en joignant plusieurs sous-requêtes.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!