2016-07-18 11 views
2

Dies ist ein Problem, das mich 2 Tage Schlaf halten.MySQL Join Renditen mehr als erwartet

Ich habe 2 Tabellen

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 

und die folgende Abfrage

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

Wenn ich print_r die Ausgabe i folgendes Ergebnis sehen werden

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 
     ) 

) 

Nur die [countviews] Ergebnis ist höher als erwartet. Ich zähle und sehe, dass die Countviews von Post 8 nicht "108", sondern "73" sein müssen. Das Fremde daran ist, dass die letzte Zählung von postid 8 '35' ist. "108" minus "35" = "73". Also sind die View-Tabellen doppelt gezählt?

RIGHT JOIN, LEFT JOIN und INNER JOIN alle das gleiche Ergebnis liefert.

+0

Du benimmst dich, als gäbe es hier ein Geheimnis. Wenn Sie jedoch die Aggregationsfunktionen und die GROUP BY-Klausel weglassen, wissen Sie genau, welche Zeilen zurückgegeben werden, wie viele (jeweils) und warum. – Strawberry

+0

Ihr mysql-Join gibt die ** erwartete ** Anzahl an Zeilen zurück. Sie müssen nur verstehen, dass es 'SUM'S (oder welche Aggregatfunktion Sie verwenden) alle Zeilen, die angezeigt werden. – KaeL

+0

Ich verstehe, in Besucher sind 3 Zeilen für postid 8 und in Ansichten 2. Dies bedeutet, dass in Ansichten eine zusätzliche Zeile auch mit der letzten Zählung erscheint. Wie kann ich die Anzahl dieser Zeile auf 0 ändern? – Paultje182

Antwort

1

Sie können hier keine Verbindung herstellen, wenn Sie zählen möchten. Die Beziehung, die Sie erstellt haben, erstellt ein Vielfaches der View-Tabelle, wenn Ihre Suchparameter mehrere Tage für dieselbe Post-ID enthalten.

Sie können das vermeiden, indem Unterabfragen:

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 

Hoffe, dass ich es richtig. Lass es mich wissen, wenn das hilft :)

+0

DANKE, das ist die Lösung !!! VIELEN DANK! – Paultje182

+0

Musste es leicht bearbeiten. Die zweite Bedingung (Gleichheit der Daten) wurde vergessen. Froh, dass ich helfen konnte. – TehSphinX

+0

Wenn ich das i.date = a.date hinzufüge, dann erhält der countvisitors nicht die guten Ergebnisse. Wenn ich das verlasse, funktioniert es gut. Vielen Dank! – Paultje182