来自具有多个计数和计算行的多个表的MYSQL查询

时间:2014-04-01 02:00:33

标签: mysql count union

迫切需要一些帮助,我有三张桌子。员工姓名的卡表,生成的潜在客户的查询表,以及作业的工作表。

我尝试进行的查询涉及返回每位员工的潜在客户数和工作数,并计算每位员工的转化率。

卡表架构如下: -

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";

然而,这显然是非常不正确的,任何帮助将不胜感激。

2 个答案:

答案 0 :(得分: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

要使用您尝试的子选择来完成它,您需要将子选择与其cards子句中的主表(WHERE)相关联:

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 :(得分: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;

与查询的主要区别在于外cards子句中的from。要获得比率,可以使用子查询:

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;