2014-11-03 89 views
0

我的模式中有5个表。从四个mysql表中选择count和sum列和where子句

首先是opn

| opnID | submitID | emailID |  opnDate  | invalidOPN | 
+-------+----------+---------+---------------------+------------+ 
| 1 | 6  | 1 | 2014-10-15 11:45:50 |  2  | 
| 2 | 6  | 2 | 2014-10-15 11:55:52 |  0  | 
| 3 | 6  | 3 | 2014-10-15 12:41:52 |  10  | 
| 4 | 7  | 2 | 2014-10-15 17:45:22 |  1  | 
| 5 | 7  | 3 | 2014-10-16 00:45:55 |  5  | 
| 6 | 6  | 5 | 2014-10-16 01:45:11 |  0  | 

我也有clk

| clkID| submitID | emailID |  clkDate  | invalidCLK | 
+-------+----------+---------+---------------------+------------+ 
| 1 | 6  | 1 | 2014-10-15 11:45:55 |  1  | 
| 2 | 6  | 2 | 2014-10-15 11:55:59 |  0  | 
| 3 | 6  | 3 | 2014-10-15 12:42:52 |  5  | 
| 4 | 7  | 3 | 2014-10-15 17:46:12 |  0  | 
| 5 | 6  | 5 | 2014-10-16 00:46:55 |  0  | 

一个users表:

| userID | firstName | secondName | 
+--------+-----------+------------+ 
| 1 | john | smith | 
| 1 | susan | bella | 

一个submission表:

| submitID | userID | 
+----------+--------+ 
| 6  | 1 | 
| 7  | 2 | 

我需要计算opn.submitID以获取打开的数量并计数clk.submitID以获取每个用户的点击次数以及invalidclk和invalidopn的总数。

这里是我的预计业绩:

| userID | fName | sName | numberOfOpen | SUM(opn.invalidOPN) | numberOfClicks | SUM(clk.invalidCLK) | 
+--------+-------+-------+--------------+---------------------+----------------+---------------------+ 
| 1 | john | smith |  4  |   12   |  4  |   6   | 
| 2 | susan | bella |  2  |   6   |  1  |   0   | 

我与这两个查询试过,但我没有达到我需要

SELECT users.userID, users.FirstName, users.SecondName, count(opn.submitID) as "Number of Opens", sum(opn.InvalidOPN) as "Number of invalid Opens" 

FROM users 

RIGHT JOIN (submission INNER JOIN opn ON opn.submitID = submission.submitID and OPNDate between "2013-10-01 00:00:00" AND "2014-10-31 23:59:59") ON submission.UserID = users.UserID group by users.userID 

UNION 

SELECT users.userID, users.FirstName, users.SecondName, count(clk.submitID) as "Number of clicks", sum(clk.InvalidCLK) as "Number of invalid clicks" 
FROM users 
RIGHT JOIN (submission INNER JOIN clk ON clk.submitID = submission.submitID and CLKDate between "2013-10-01 00:00:00" AND "2014-10-31 23:59:59") ON submission.UserID = users.UserID group by users.userID 

SELECT users.userID, users.FirstName, users.SecondName, count(opn.submitID) as "Number of Opens", sum(opn.InvalidOPN) as "Number of invalid Opens", count(clk.submitID) as "Number of clicks", sum(clk.InvalidCLK) as "Number of invalid clicks" 

FROM users, submission, clk, opn 

where opn.submitID = submission.submitID and clk.submitID = submission.submitID 
And CLKDate between "2013-10-01 00:00:00" AND "2014-10-31 23:59:59" 
AND submission.UserID = users.UserID group by users.userID 

结果请帮助我,告诉我我需要改变什么。

+2

Hooray for RIGHT JOIN。尼斯。 – Strawberry 2014-11-03 17:45:14

回答

1

这样做的主要问题是,您需要将表加入对方,并获得opn和clk记录的每个组合。在你的土地最多需要使用COUNT(DISTINCT some_field_name)计数唯一值这样的情况: -

SELECT users.UserId 
     COUNT(DISTINCT opn.OPNID), 
     COUNT(DISTINCT clk.CLKID) 
FROM users 
LEFT OUTER JOIN submission ON users.UserId = submission.UserId 
LEFT OUTER JOIN opn ON submission.SubmitID = opn.SubmitID 
LEFT OUTER JOIN clk ON submission.SubmitID = clk.SubmitID 
GROUP BY users.UserId 

但是这并不在此情况下帮你还需要invalid___字段的总和。

因此,我建议使用几个子查询,一个用于clk,一个用于opn。这些得到的计数和由用户ID分组的总和。这些子查询的结果将加入到用户表中。

事情是这样的: -

SELECT users.UserId, 
     users.fName, 
     users.sName, 
     numberOfOpen, 
     COALESCE(invalidopnsum, 0), 
     numberOfClicks, 
     COALESCE(invalidclksum, 0) 
FROM users 
LEFT OUTER JOIN 
(
    SELECT submission.UserId, COUNT(opn.SubmitID) AS numberOfOpen, SUM(opn.InvalidOPN) AS invalidopnsum 
    FROM submission 
    LEFT OUTER JOIN opn ON submission.SubmitID = opn.SubmitID 
    GROUP BY submission.UserId 
) opn1 
ON users.UserId = opn1.UserId 
LEFT OUTER JOIN 
(
    SELECT submission.UserId, COUNT(clk.SubmitID) AS numberOfClicks, SUM(clk.InvalidCLK) AS invalidclksum 
    FROM submission 
    LEFT OUTER JOIN clk ON submission.SubmitID = clk.SubmitID 
    GROUP BY submission.UserId 
) clk1 
ON users.UserId = clk1.UserId 
+1

'COALESCE(invalidopnsum,0)'后面只有一个逗号。否则,这将返回正确的结果。(http://sqlfiddle.com/#!2/17b164/7) – AdamMc331 2014-11-03 18:05:48

+1

谢谢@ McAdam331 – Kickstart 2014-11-03 18:09:21

0

这比你想象的更容易。所有你需要做的就是将所有的表连接在一起,并使用一些聚合函数。您可以通过userID列加入用户,您可以使用submitID列将其与clk和opn表加入。您可以使用COUNT()获取打开和点击次数,并使用SUM()获取无效列的总数。但是,一次完成这些计算将不起作用,因为某些事实将被复制,所以我建议您分别执行每个查询并加入它们。

查询看起来是这样的:

SELECT t.userID, t.firstName, t.secondName, t.numOpen, t.totalInvalidOpen, w.numClick, w.totalInvalidClick 
FROM (SELECT u.userID, u.firstName, u.secondName, COUNT(*) AS numOpen, SUM(o.invalidOPN) AS totalInvalidOpen 
     FROM users u 
     JOIN submission s ON s.userID = u.userID 
     JOIN opn o ON o.submitID = s.submitID 
     GROUP BY u.userID 
    ) t 
JOIN (SELECT u.userID, u.firstName, u.secondName, COUNT(*) AS numClick, SUM(c.invalidCLK) AS totalInvalidClick 
     FROM users u 
     JOIN submission s ON s.userID = u.userID 
     JOIN clk c ON c.submitID = s.submitID 
     GROUP BY u.userID 
    ) w 
ON w.userID = t.userID; 

和它的作品!这是你的SQL Fiddle注意:您在问题中设置的结果不正确,因为用户1的无效打开总数只有12个。

+0

小问题是,这将只会带回一个用户,如果他们有两个记录opn和clk表。 – Kickstart 2014-11-03 18:11:25

+0

好的。那么我应该如何离开加入用户表? – AdamMc331 2014-11-03 18:49:50

+0

@Kickstart我想我应该只是答应你的回答哈哈。如果我改变我的左加入,我会和你的完全一样。 – AdamMc331 2014-11-03 18:50:24