2014-11-03 3 views
0

내 스키마에 5 개의 테이블이 있습니다.count 및 sum 열이있는 네 개의 mysql 테이블과 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 | 

클릭 수와 각 사용자에 대한 invalidclk 및 invalidopn의 합계를 얻으려면 open 및 count clk.submitID 수를 얻으려면 opn.submitID를 계산해야합니다. 여기

내 예상 결과입니다 : 그 두 개의 쿼리를 시도

| 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

우연한 만회. 좋은. – Strawberry

답변

1

이 작업의 주된 문제점은 서로 테이블을 조인하고 opn 및 clk 레코드의 모든 조합을 가져 오는 것입니다. 당신은 또한 invalid___ 필드의 합을 필요로하지만

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 

이 경우 도움이되지 않습니다 : - 당신은 고유 한 값을 계산하는을 COUNT (DISTINCT some_field_name)를 사용할 필요 최대 착륙 이러한 상황에서 .

나는 clk 용과 opn 용의 두 가지 하위 쿼리를 사용하는 것이 좋습니다. 이것들은 카운트와 합계를 사용자 ID별로 그룹화합니다. 이 하위 쿼리의 결과는 users 테이블에 조인됩니다. 이 같은

뭔가 : -

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

+1

감사합니다. @ McAdam331 – Kickstart

0

이것은 당신이 생각하는 것보다 쉽다. 모든 테이블을 함께 결합하고 사용자에게 일부 집계 함수를 추가하기 만하면됩니다. 사용자 ID 열의 제출을 ​​통해 사용자를 참여시킬 수 있으며 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

+0

잘자요. 이전처럼 사용자 테이블에 가입해야합니까? – AdamMc331

+0

@Kickstart 제 생각에 저는 당신의 대답 인 하하에게 그냥 인정해야한다고 생각합니다. 만약 내가 왼쪽 조인으로 바뀌면 나는 너와 똑같을거야. – AdamMc331