2010-12-12 77 views
1

Je courais la requête suivantedes fonctions d'agrégation multiples dans MySQL avec des conditions différentes

SELECT t2.lender_name, COUNT(t1.id) as total,  
SUM(t1.submit_date IS NULL) AS num_incomplete, 

(SELECT AVG(DATEDIFF(due_date,now())) 
    FROM table_1 WHERE submit_date IS NULL) as avg_incomplete_due_in, 
(SELECT AVG(DATEDIFF(due_date,submit_date)) 
    FROM table_1 WHERE submit_date IS NOT NULL) as avg_complete_turnaround 

FROM table_1 
INNER JOIN table_2 t2 ON t2.fid = t1.id 
WHERE t1.due_date <= '2010-12-31' 
GROUP BY t2.lender_name 

Le total, num_incomplete et le groupement fonctionne très bien. Les valeurs de sous-sélection sont les mêmes pour chaque ligne. Je voudrais aussi ces valeurs groupées par le nom de prêteur et retournées dans le même jeu d'enregistrements. Aucune suggestion?

+0

alias t1 n'est pas défini dans votre exemple – newtover

Répondre

3

Votre code actuel manque juste une relation entre la requête externe et les sous-requêtes. En théorie, il vous suffit de corréler les requêtes:

SELECT t2.lender_name, COUNT(t1.id) as total, 
SUM(t1.submit_date IS NULL) AS num_incomplete, 
(SELECT AVG(DATEDIFF(due_date,now())) 
    FROM table_1 t3 
    WHERE submit_date IS NULL 
    AND t3.lender_name = t2.lender_name) as avg_incomplete_due_in, 
(SELECT AVG(DATEDIFF(due_date,submit_date)) 
    FROM table_1 
    WHERE submit_date IS NOT NULL 
    AND t3.lender_name = t2.lender_name) as avg_complete_turnaround 
FROM table_1 t1 
INNER JOIN table_2 t2 ON t2.fid = t1.id 
WHERE t1.due_date <= '2010-12-31' 
GROUP BY t2.lender_name 

Dans la pratique, la requête est pas très efficace dans MySQL. Vous pouvez réécrire de la manière suivante:

SELECT 
    t2.lender_name, 
    COUNT(*) as total, 
    SUM(t1.submit_date IS NULL) AS num_incomplete, 
    AVG(IF(t1.submit_date IS NULL, 
     DATEDIFF(t1.due_date, NOW()), 
     NULL)) AS avg_incomplete_due_in, 
    AVG(DATEDIFF(due_date,submit_date)) AS avg_complete_turnaround 
FROM table_1 t1 
INNER JOIN table_2 t2 ON t2.fid = t1.id 
WHERE t1.due_date <= '2010-12-31' 
GROUP BY t2.lender_name 
+0

J'ai implémenté votre amélioration suggérée et cela a fonctionné !! Merci beaucoup. – pistolshrimp

0

somme si, et compter si l'affaire

SELECT t2.lender_name, COUNT(t1.id) as total,  
SUM(t1.submit_date IS NULL) AS num_incomplete, 
SUM(IF(table_1.submit_date IS NULL,DATEDIFF(table_1.due_date,now()),0))/COUNT(IF(table_1.submit_date IS NULL,1,NULL)) as avg_incomplete_due_in 
SUM(IF(table_1.submit_date IS NOT NULL,DATEDIFF(table_1.due_date,submit_date),0))/COUNT(IF(table_1.submit_date IS NOT NULL,1,NULL)) as avg_complete_turnaround 

FROM table_1 
INNER JOIN table_2 t2 ON t2.fid = t1.id 
WHERE t1.due_date <= '2010-12-31' 
GROUP BY t2.lender_name 
+0

Cela devrait fonctionner, mais trop de lettres pour le cas. Vous venez d'implémenter la fonction AVG =) – newtover