2011-05-05 5 views
3

J'essaie de créer une requête SQL qui varie en fonction des options envoyées depuis un formulaire. Au sein de ce que je veux essayer de partager les effets de l'instruction de clause WHERE principale avec la clause WHERE sur une sous-requête. Prenons par exemple le nombre de lignes, où total_passfail = "Pass". Ce nombre peut cependant changer en raison de l'implication de la fonction WHERE des requêtes principales (dans la fonction principale WHERE j'ai 8 options possibles telles que la date, l'utilisateur, l'équipe, le département qui façonnent les données globales en conséquence).Sous-requête MYSQL COUNT WHERE

Est-il possible de faire en sorte que la clause WHERE globale affecte la sous-requête plutôt que de devoir ajouter 8 autres WHERE à chaque sous-requête. Effectivement je veux juste que la clause WHERE de sous-requête agisse au-dessus de l'ensemble de données que la requête principale retourne.

Toute aide serait grandement appréciée.

$query = $this->db->join('users', 'users.staff_id = quality.staff_id') 
->join('user_info', 'user_info.staff_id = users.staff_id') 
->join('teams', 'teams.team_id = users.team_id') 
->join('departments', 'teams.dept_id = departments.dept_id') 
->join('quality_results', 'quality_results.qms_id = quality.qms_id') 
->where('quality.published !=', "") 
->where('quality.published !=', "0000-00-00 00:00:00") 
->select('users.staff_id, user_info.name, user_info.surname, teams.team_name, departments.dept_name, COUNT(quality.qms_id) AS num_assessments, (SELECT (SUM(quality_results.total_result)/COUNT(quality_results.total_result))) AS average_result, (SELECT COUNT(quality_results.total_passfail) FROM quality_results WHERE quality_results.total_passfail = "Pass") AS pass_count'); 

if (strlen($query_array['task_date_from'])) { 
$query->where('quality.task_datetime >=', $query_array['task_date_from']); 
} 
if (strlen($query_array['task_date_to'])) { 
$query->where('quality.task_datetime <=', $query_array['task_date_to']); 
} 
    (+ 4 MORE IF STATEMENTS HERE) 

$result = $query->get('quality'); 

J'ai aussi fatigué remplacer la sous-requête à ce qui suit, mais obtenir une erreur à la place:

SUM(IF(quality_results.total_passfail = "Pass", 1,0)) AS pass_count 

Voici mon code SQL brut:

SELECT `users`.`staff_id`, `user_info`.`name`, `user_info`.`surname`, `teams`.`team_name`, `departments`.`dept_name`, COUNT(quality.qms_id) AS num_assessments, (SELECT (AVG(quality_results.total_result))) AS average_result, (SELECT COUNT(quality_results.total_passfail) FROM quality_results WHERE quality_results.total_passfail = "Pass") AS pass_count FROM (`quality`) JOIN `users` ON `users`.`staff_id` = `quality`.`staff_id` JOIN `user_info` ON `user_info`.`staff_id` = `users`.`staff_id` JOIN `teams` ON `teams`.`team_id` = `users`.`team_id` JOIN `departments` ON `teams`.`dept_id` = `departments`.`dept_id` JOIN `quality_results` ON `quality_results`.`qms_id` = `quality`.`qms_id` JOIN `quality_tasks` ON `quality`.`task_id` = `quality_tasks`.`task_id` WHERE `quality`.`published` != '' AND `quality`.`published` != '0000-00-00 00:00:00' AND `quality`.`task_datetime` >= '2011-04-09' AND `quality`.`task_datetime` <= '2011-05-09' AND `teams`.`dept_id` = '1' 
+0

S'il vous plaît poster toute la requête (pas avec 8, mais avec 1 ou 2 conditions sur le WHERE) afin que nous puissions voir ce que vous voulez dire. –

+0

En ce moment, mon seul commentaire est que vous pouvez utiliser 'AVG()' au lieu de 'SUM()/COUNT()'. –

+0

Quelqu'un at-il une idée de comment je peux résoudre ce problème? –

Répondre

4

Formatted SQL:

SELECT `users`.`staff_id`, `user_info`.`name`, `user_info`.`surname`, 
     `teams`.`team_name`, `departments`.`dept_name`, 
     COUNT(quality.qms_id) AS num_assessments, 
     (SELECT (AVG(quality_results.total_result))) AS average_result, 
     (SELECT COUNT(quality_results.total_passfail) 
     FROM quality_results 
     WHERE quality_results.total_passfail = "Pass") AS pass_count 
FROM (`quality`) 
JOIN `users` ON `users`.`staff_id` = `quality`.`staff_id` 
JOIN `user_info` ON `user_info`.`staff_id` = `users`.`staff_id` 
JOIN `teams` ON `teams`.`team_id` = `users`.`team_id` 
JOIN `departments` ON `teams`.`dept_id` = `departments`.`dept_id` 
JOIN `quality_results` ON `quality_results`.`qms_id` = `quality`.`qms_id` 
JOIN `quality_tasks` ON `quality`.`task_id` = `quality_tasks`.`task_id` 
WHERE `quality`.`published` != '' 
    AND `quality`.`published` != '0000-00-00 00:00:00' 
    AND `quality`.`task_datetime` >= '2011-04-09' 
    AND `quality`.`task_datetime` <= '2011-05-09' 
    AND `teams`.`dept_id` = '1' 

Votre pass_count ne prend actuellement pas en compte main where, car c'est une sous-requête. Mais vous pouvez ajouter pour chaque colonne de gauche comme nb_passe rejoint quality_results, comme ici:

SELECT 
    `users`.`staff_id`, `user_info`.`name`, `user_info`.`surname`, `teams`.`team_name`, `departments`.`dept_name`, 
    COUNT(quality.qms_id) AS num_assessments, 
    (SELECT (AVG(quality_results.total_result))) AS average_result, -- It`s a total average result -- as a whole on all system 
    count(quality_results_passed.total_passfail) AS pass_count -- And this will be quality_results, that will take into account your main where 
FROM (`quality`) 
JOIN `users` ON `users`.`staff_id` = `quality`.`staff_id` 
JOIN `user_info` ON `user_info`.`staff_id` = `users`.`staff_id` 
JOIN `teams` ON `teams`.`team_id` = `users`.`team_id` 
JOIN `departments` ON `teams`.`dept_id` = `departments`.`dept_id` 
JOIN `quality_results` ON `quality_results`.`qms_id` = `quality`.`qms_id` 
LEFT JOIN `quality_results` as `quality_results_passed` 
    ON `quality_results_passed`.`qms_id` = `quality`.`qms_id` 
    and quality_results.total_passfail = "Pass" 
JOIN `quality_tasks` ON `quality`.`task_id` = `quality_tasks`.`task_id` 
WHERE `quality`.`published` != '' AND `quality`.`published` != '0000-00-00 00:00:00' 
AND `quality`.`task_datetime` >= '2011-04-09' AND `quality`.`task_datetime` <= '2011-05-09' AND `teams`.`dept_id` = '1' 
+0

Fonctionne parfaitement et juste un jour avant mon uni date limite, merci pour votre aide :) –

0

Les SUM(IF(EXPR, 1, 0)) fonctionne très bien. C'est ce que j'ai utilisé et semble effectuer avec un risque plus faible que les sélections imbriquées. Corrigez simplement votre erreur SQL.