2016-07-18 33 views
2

這是一個讓我連續2天睡眠的問題。MySQL加入回報超過預期

我有2個表

views 

id | postid | date  | count 
================================= 
13 | 8 | 2016-07-16 | 38 
16 | 8 | 2016-07-17 | 35 
15 | 9 | 2016-07-16 | 7 
17 | 9 | 2016-07-17 | 32 
14 | 12 | 2016-07-16 | 17 
18 | 12 | 2016-07-17 | 13 


visitors 

id | postid | date  | ip 
================================= 
13 | 8 | 2016-07-16 | 127.0.0.1 
17 | 8 | 2016-07-17 | 127.0.0.1 
18 | 8 | 2016-07-17 | 127.0.0.1 
16 | 9 | 2016-07-16 | 127.0.0.1 
19 | 9 | 2016-07-17 | 127.0.0.1 
14 | 12 | 2016-07-16 | 127.0.0.1 
15 | 12 | 2016-07-16 | 127.0.0.1 
20 | 12 | 2016-07-17 | 127.0.0.1 
21 | 12 | 2016-07-17 | 127.0.0.1 

和下面的查詢

$query = $wpdb->get_results(" 
    SELECT 
     SUM(a.count) AS countviews, 
     COUNT(b.ip) AS countvisitors, 
     a.postid 
    FROM views a 
    RIGHT JOIN visitors b 
     ON a.postid=b.postid 
     AND a.date=b.date 
    WHERE 
     a.date 
    BETWEEN 
     DATE_SUB('2016-07-17', INTERVAL 3 DAY) 
    AND 
     '2016-07-17' 
    GROUP BY 
     a.postid 
    ORDER BY 
     countviews DESC 
"); 

當我print_r的輸出,我會看到以下結果

Array 
(
    [0] => stdClass Object 
     (
      [countviews] => 108 
      [countvisitors] => 3 
      [postid] => 8 
     ) 

    [1] => stdClass Object 
     (
      [countviews] => 60 
      [countvisitors] => 4 
      [postid] => 12 
     ) 

    [2] => stdClass Object 
     (
      [countviews] => 39 
      [countvisitors] => 2 
      [postid] => 9 
     ) 

) 

只有[countviews]結果更高,然後擴大。我要數一數,看看postid 8的countviews不能是'108',而是'73'。更奇怪的是,postid 8的最後一個計數是'35'。 '108'減去'35'='73'。所以視圖表是雙重計數?

RIGHT JOIN,LEFT JOIN和INNER JOIN給出了所有相同的結果。

+0

你表現就像這裏有一些神祕。但是,如果您省略聚合函數和GROUP BY子句,那麼您將確切知道返回哪些行,每個行的數量以及原因。 – Strawberry

+0

您的mysql連接返回**期望的**行數。你只需要理解它所有顯示的行都是SUM(或者你使用的任何聚合函數)。 – KaeL

+0

據我所知,訪問者在postid 8和view 2中有3行。這意味着在視圖中,最後一行還會顯示一行。我如何將該行的計數更改爲0? – Paultje182

回答

1

如果要計數,則無法在此處進行連接。您所建立的關係是創建視圖表的倍數,以防您的搜索參數中存在多個日期以用於相同的postid。

可避免通過使用子查詢:

SELECT 
    SUM(a.count) AS countviews, 
    (SELECT COUNT(b.ip) FROM visitors i WHERE b.date BETWEEN DATE_SUB("2016-07-17", INTERVAL 3 DAY) AND "2016-07-17" AND i.postid = a.postid) AS countvisitors, 
    a.postid 
FROM views a 
WHERE 
    a.date 
BETWEEN 
    DATE_SUB('2016-07-17', INTERVAL 3 DAY) 
AND 
    '2016-07-17' 
GROUP BY 
    a.postid 
ORDER BY 
    countviews DESC 

希望我這樣做是正確。讓我知道如果這有助於:)

+0

謝謝,這是解決方案!謝謝! – Paultje182

+0

只好稍微修改一下。忘記了第二個條件(日期平等)。很高興我能幫上忙。 – TehSphinX

+0

當我添加i.date = a.date時,計數器並沒有給出好的結果。當我離開時,工作得很好。謝謝! – Paultje182