2014-11-03 103 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