2014-04-01 50 views
1

拼命需要一些幫助,我有三個表。用於員工姓名的卡片表,用於生成的銷售線索的查詢表以及用於作業的工作表。來自多個表的多重計數和計算行的MYSQL查詢

我試圖做一個查詢,涉及返回每個員工的潛在客戶數量和職位數量,並計算每個員工的轉化率。

卡表架構是這樣的: -

cards 
+-----------+------------+-------------+ 
| PK_CardID | LastName | FirstName | 
+-----------+------------+-------------+ 
|   1 | Andrews | John  | 
|   2 | Smith  | Cynthia  | 
|   3 | Jones  | Adam  | 
+-----------+------------+-------------+ 

查詢表架構是這樣的: -

+--------------+-----------+------------+ 
| PK_EnquiryID | FK_CardID | DateAdded | 
+--------------+-----------+------------+ 
|   1 |   1 | 1995-01-21 | 
|   2 |   3 | 1995-01-22 | 
|   3 |   1 | 1995-01-23 | 
|   4 |   2 | 1995-01-21 | 
+--------------+-----------+------------+ 

工作表模式是這樣的: -

+----------+-----------+------------+ 
| PK_JobID | FK_CardID | DateAdded | 
+----------+-----------+------------+ 
|  1 |   3 | 1995-01-25 | 
|  2 |   2 | 1995-01-26 | 
|  3 |   3 | 1995-01-24 | 
|  4 |   1 | 1995-01-26 | 
+----------+-----------+------------+ 

所以我想要返回如下內容

+-----------+------------+-------------+----------------+-----------+-----------------+ 
| PK_CardID | LastName | FirstName | countEnquiries | countJobs | ConversionRatio | 
+-----------+------------+-------------+----------------+-----------+-----------------+ 
|   1 | Andrews | John  |    2 |   1 | 50%    | 
|   2 | Smith  | Cynthia  |    1 |   1 | 100%   | 
|   3 | Jones  | Adam  |    1 |   2 | 200%   | 
+-----------+------------+-------------+----------------+-----------+-----------------+ 

到目前爲止,我的SQL看起來像這樣

SELECT PK_CardID, LastName, FirstName 
       (SELECT count(PK_EnquiryID) FROM enquiries WHERE PK_Cardid = FK_CardID) as countEnq, 
       (SELECT count(PK_JobID) FROM jobs WHERE PK_CardID = FK_CardID) as countJob 
       FROM enquiries"; 

然而,這顯然是不正確極,任何幫助,將不勝感激。

回答

1

有幾種方法可以處理,而你選擇的子查詢就是其中之一,但它往往很慢。由於COUNT()聚合必須單獨應用於jobsenquiries表,您可以加入兩個子查詢,這些子查詢返回每個PK_CardID的計數。

SELECT 
    c.PK_CardID, 
    FirstName, 
    LastName, 
    enquiries, 
    jobs, 
    jobs/enquiries * 100 AS conversionratio 
FROM 
    cards c 
    /* Separately retrieve the count of enquiries and count of jobs 
    LEFT JOINs are used in case there are none returned from either 
    related table */ 
    LEFT JOIN (
    SELECT FK_CardID, COUNT(*) AS enquiries 
    FROM enquiries 
    GROUP BY FK_CardID 
) e ON c.PK_CardID = e.FK_CardID 
    LEFT JOIN (
    SELECT FK_CardID, COUNT(*) AS jobs 
    FROM jobs 
    GROUP BY FK_CardID 
) j ON c.PK_CardID = j.FK_CardID 

這裏是一個演示:http://sqlfiddle.com/#!2/915940/1

要完成使用子查詢,你嘗試它,你需要在它的WHERE子句相關子選擇主表(cards):

SELECT 
    c.PK_CardID, 
    FirstName, 
    LastName, 
    (SELECT COUNT(*) FROM enquiries WHERE FK_CardID = c.PK_CardID) AS enquiries, 
    (SELECT COUNT(*) FROM jobs WHERE FK_CardID = c.PK_CardID) AS jobs, 
    /* Unless the whole thing is wrapped in a subquery, you need to *recalculate* these subselects 
    to use them in the calculated field, which is very slow. The method above 
    is more efficient. */ 
    (SELECT COUNT(*) FROM jobs WHERE FK_CardID = c.PK_CardID)/(SELECT COUNT(*) FROM enquiries WHERE FK_CardID = c.PK_CardID) * 100 as conversionratio 
FROM 
    cards c 

http://sqlfiddle.com/#!2/915940/2

...避免重新計算整個事情:

SELECT 
    PK_CardID, 
    FirstName, 
    LastName, 
    enquiries, 
    jobs, 
    /* calculation performed in the outer query with values from the inner's subselects */ 
    jobs/enquiries * 100 AS conversionratio 
FROM (
    SELECT 
    c.PK_CardID, 
    FirstName, 
    LastName, 
    (SELECT COUNT(*) FROM enquiries WHERE FK_CardID = c.PK_CardID) AS enquiries, 
    (SELECT COUNT(*) FROM jobs WHERE FK_CardID = c.PK_CardID) AS jobs 
    FROM cards c 

)AS包裝

1

你試圖寫看起來像這樣的查詢:

SELECT c.PK_CardID, c.LastName, c.FirstName 
     (SELECT count(*) FROM enquiries e WHERE c.PK_Cardid = e.FK_CardID) as countEnq, 
     (SELECT count(*) FROM jobs j WHERE c.PK_CardID = j.FK_CardID) as countJob 
FROM cards c; 

從查詢的主要區別是外from子句中的cards。爲了得到這個比例,你可以使用子查詢:

SELECT PK_CardID, LastName, FirstName, countEnq, countJob, 
     100*(countEnq/countJob) as ConversionRatio 
FROM (SELECT c.PK_CardID, c.LastName, c.FirstName 
      (SELECT count(*) FROM enquiries e WHERE c.PK_Cardid = e.FK_CardID) as countEnq, 
      (SELECT count(*) FROM jobs j WHERE c.PK_CardID = j.FK_CardID) as countJob 
     FROM cards c 
    ) c;