2011-09-14 72 views
1

我确信有更好的方法来做到这一点。它查看applications表并收集每个作业的特定状态的所有应用程序。优化复杂的SQL查询

所以它看起来像这样:

pending | screened | interviewed | accepted | offer | hired | job title 
0   0   0    0   0  2  dirt mover 
2   0   1    1   0  1  tree planter 
7   2   1    1   1  3  hole digger 

这里是SQL(与可读性去除多余的工会列,如果你可以调用这个查询可读)

select sum(pending) as pending, sum(screened) as screened, sum(interviewed) 
as interviewed, sum(accepted) as accepted, sum(offer) as offer, sum(hired) 
as hired, sum(declined) as declined, sum(rejected) as rejected, title, jobid 
from 
(

(select count(j.job_id) as pending, j.title as title, j.job_id as jobid from 
applications a, jobs j where j.job_id = a.job_id and status = 'Pending' group by 
j.job_id) 

union 

(select count(j.job_id) as screened, j.title as title, j.job_id as jobid from 
applications a, jobs j where j.job_id = a.job_id and status = 'Screened' group by 
j.job_id) 

union 

(select count(j.job_id) as interviewed, j.title as title, j.job_id as jobid from 
applications a, jobs j where j.job_id = a.job_id and status = 'Interviewed' group by 
j.job_id) 

union 

(select count(j.job_id) as accepted, j.title as title, j.job_id as jobid from 
applications a, jobs j where j.job_id = a.job_id and status = 'Accepted' group by 
j.job_id) 

union 

(select count(j.job_id) as offer, j.title as title, j.job_id as jobid from 
applications a, jobs j where j.job_id = a.job_id and status = 'Offer Made' group by 
j.job_id) 

union 

(select count(j.job_id) as hired, j.title as title, j.job_id as jobid from 
applications a, jobs j where j.job_id = a.job_id and status = 'Offer Accepted' group 
by j.job_id) 

union 

(select count(j.job_id) as declined, j.title as title, j.job_id as jobid from 
applications a, jobs j where j.job_id = a.job_id and status = 'Offer Declined' group 
by j.job_id) 

union 

(select count(j.job_id) as rejected, j.title as title, j.job_id as jobid from 
applications a, jobs j where j.job_id = a.job_id and status = 'Rejected' group by 
j.job_id) 

) as summ group by title order by title 

下面是SHOW CREATE TABLE应用

CREATE TABLE IF NOT EXISTS `applications` (
    `app_id` int(5) NOT NULL auto_increment, 
    `job_id` int(5) NOT NULL, 
    `status` varchar(25) NOT NULL, 
    `reviewed` datetime NOT NULL, 
    PRIMARY KEY (`app_id`), 
    UNIQUE KEY `app_id` (`app_id`), 
    KEY `job_id` (`job_id`), 
    KEY `status` (`status`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2720 ; 

下面是SHOW CREATE TABLE工作

CREATE TABLE IF NOT EXISTS `jobs` (
    `job_id` int(5) NOT NULL auto_increment, 
    `title` varchar(25) NOT NULL, 
    PRIMARY KEY (`app_id`), 
    KEY `job_id` (`job_id`), 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 
+0

你需要什么?你期望从查询中得到什么? – santiagobasulto

+0

结果集超过11秒。结果表格在我的问题的顶部。 –

+1

使用InnoDB !!!!!! – santiagobasulto

回答

3

它看起来像你在做一个PIVOT /交叉表查询。像这样的东西应该可以做到。

SELECT COUNT(CASE 
       WHEN status = 'Pending' THEN 1 
      END) AS pending, 
     COUNT(CASE 
       WHEN status = 'Screened' THEN 1 
      END) AS screened, 
     /*Remaining ones left as an exercise for the reader*/ 
     title 
FROM applications a 
     JOIN jobs j 
     ON j.job_id = a.job_id 
GROUP BY title 
ORDER BY title 
+0

那该死的。辉煌。 –

0

首先,需要注意以下几点:

  1. 不要使用交叉连接(西塔连接)。这确实减慢查询下来:

    SELECT * FROM TABLE_1,TABLE_2 WHERE table_1.id = table_2.t1_id

使用,而不是:

SELECT * FROM table_1 INNER JOIN table_2 ON(table_1.id = table_2.t1_id) 
  1. 主键已经UNIQUE KEYS

现在,我就是这么做的:

SELECT 
    SUM(a.app_id), 
    a.status 
FROM 
    applications a INNER JOIN 
    jobs j ON (j.job_id=a.job_id) 
GROUP BY 
    j.job_id, 
    a.status 

对于这个简单的查询,你应该得到类似的东西:

JOB_TITLE | STATUS  | COUNT 
dirt mover | pending  | 0 
dirt mover | screened  | 0 
dirt mover | interviewed | 0 
dirt mover | accepted  | 0 
dirt mover | offer   | 0 
dirt mover | hired   | 2 

tree planter | pending  | 2 
tree planter | screened  | 0 
tree planter | interviewed | 1 
tree planter | accepted  | 1 
tree planter | offer   | 0 
tree planter | hired   | 1 
... 

注意,标题是重复的,但是这不是一个问题,becouse你可以得到相同的信息。该查询将快几倍,并且更简单。