2011-08-28 79 views
0

(查询更新的cdhowie评论)MySQL的子查询与重写问题

计数这里的情况。 我想要“统计分配给每个工作人员的任务位置类型1,2和任务部门类型3,4内的任务数量”。

假设我有以下各表

Task : id, Name 
Task_Worker_Combi : Task_id, Worker_id 
Worker : id, Name 
Task_Location_Combi : Task_id, Location_id 
Task_Department_Combi : Task_id, Department_id 
Location : id, Name 
Department : id, Name 

我得到尽可能如下:(但是,因为它永远都必须有查询的一些错误)

SELECT W.id, W.Name, COUNT(TWC.Task_id) AS Count 
FROM Worker AS W 
LEFT JOIN Task_Worker_Combi AS TWC 
    ON (W.id=TWC.Worker_id) 
WHERE W.id>0 AND TWC.Task_id IN 
(
    SELECT T.id 
    FROM Task as T 
    LEFT JOIN (Task_Location_Combi AS TLC, Task_Department_Combi AS TDC) 
     ON (T.id=TLC.Task_id AND T.id=TDC.Task_id) 
    WHERE 1 AND TLC.Location_id IN (1,2) AND TDC.Department_id IN (3,4) 
    GROUP BY T.id 
) 
GROUP BY W.id 
ORDER BY W.Name 

没有这个子查询它返回“无条件分配给每个工人的任务数量”罚款。

AND TWC.Task_id IN 
(
    SELECT T.id 
    FROM Task as T 
    LEFT JOIN (Task_Location_Combi AS TLC, Task_Department_Combi AS TDC) 
     ON (T.id=TLC.Task_id AND T.id=TDC.Task_id) 
    WHERE 1 AND TLC.Location_id IN (1,2) AND TDC.Department_id IN (3,4) 
    GROUP BY T.id 
) 

哪里出错了,你将如何重写这个查询来有效地工作?请帮助我一个人。我在这里呆了一个多星期了!

实际查询如下。 (假设Job为Task and Worker as Industry as Industry from above查询简体)

EXPLAIN SELECT id, Name, COUNT(J.Industry) AS Count 
FROM industry_db.industry AS I 
LEFT JOIN job_db.industry AS J ON (I.id = J.Industry) 
WHERE I.id >0 
AND J.Job 
IN (

SELECT t1.id 
FROM job_db.job AS t1 
LEFT JOIN (
company_db.company AS t2, job_db.industry AS t3, location_db.city AS t4, job_db.function AS t5, job_db.tag AS t6, job_db.degree AS t7, location_db.state AS t8, location_db.group AS t9 
) ON (t1.Company = t2.id 
AND t1.id = t3.Job 
AND t1.City = t4.id 
AND t1.id = t5.Job 
AND t1.id = t6.Job 
AND t1.id = t7.Job 
AND t1.State = t8.id 
AND t1.State_Group = t9.id) 
WHERE 1 
AND t1.Open = '1' 
GROUP BY t1.id) 
GROUP BY id 
HAVING Count >0 
ORDER BY Name 

而phpmyadmin的解释结果如下。

id select_type table type possible_keys key key_len ref rows Extra 
1 PRIMARY I range PRIMARY,id PRIMARY 1 NULL 39 Using where; Using temporary; Using filesort 
1 PRIMARY J ref Industry Industry 1 industry_db.I.id 403 Using where 
2 DEPENDENT SUBQUERY t1 index NULL PRIMARY 4 NULL 2868 Using where 
2 DEPENDENT SUBQUERY t9 eq_ref PRIMARY PRIMARY 1 job_db.t1.State_Group 1 Using index 
2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY PRIMARY 2 job_db.t1.Company 1 Using index 
2 DEPENDENT SUBQUERY t8 eq_ref PRIMARY PRIMARY 1 job_db.t1.State 1 Using index 
2 DEPENDENT SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 job_db.t1.City 1 Using index 
2 DEPENDENT SUBQUERY t7 ref PRIMARY PRIMARY 4 job_db.t1.id 1 Using index 
2 DEPENDENT SUBQUERY t3 ref Job Job 4 job_db.t1.id 1 Using index 
2 DEPENDENT SUBQUERY t5 ref PRIMARY PRIMARY 4 job_db.t7.Job 1 Using index 
2 DEPENDENT SUBQUERY t6 ref PRIMARY PRIMARY 4 job_db.t7.Job 2 Using index 
+1

第一步优化查询的时候:使用'EXPLAIN',查找表扫描。 – cdhowie

+1

另外,这是你使用的真正的查询? “W”表来自哪里?我没有看到它在查询中的任何位置,在'FROM'或'JOIN'子句中定义。 – cdhowie

+1

由于我们在TWC.Task_Id ..... –

回答

3

试试这个:

SELECT w.id, w.Name, COUNT(tw.Task_id) 
FROM Worker AS w 
LEFT JOIN Task_Worker_Combi AS tw 
ON(
    w.id = tw.Worker_id AND 
    EXISTS(SELECT Task_id FROM Task_Location_Combi 
      WHERE Task_id = tw.TaskId AND Location_id IN(1, 2)) AND 
    EXISTS(SELECT Task_id FROM Task_Department_Combi 
      WHERE Task_id = tw_TaskId AND Department_id IN(3, 4)) 
) 
+0

哇这是一个新的rewrtie。我会尝试并让你知道。再次感谢你。 – user706087

+0

这工作,但我得到相同的时候我“选择w.id,w.Name,COUNT(tw.Task_id)从工人AS w左连接Task_Worker_Combi AS TW ON(w.id = tw.Worker_id)WHERE EXISTS(SELECT Task_id FROM Task_Location_Combi WHERE Task_id = tw。TaskId AND Location_id IN(1,2))AND EXISTS(SELECT Task_id FROM Task_Department_Combi WHERE Task_id = tw_TaskId AND Department_id IN(3,4))“。这是错误的吗? – user706087

+0

@user您的版本适用于没有匹配的工作人员任务你没有得到任何行,用我原来的查询,你为每一个零计数的工人得到一个行 – nobody