2016-06-27 21 views
0

Ich habe eine Tabelle wie folgt aus:Wie kann ich alle Zeilen einer Tabelle basierend auf den Werten einer anderen Tabelle aktualisieren?

// requests 
+----+----------------+----------------+-------------+ 
| id | user_id  |  ip  | unix_time | 
+----+----------------+----------------+-------------+ 
| 1 | 12353   | NULL   | 1339412843 | 
| 2 | 12353   | NULL   | 1339412864 | 
| 3 | NULL   | 178.253.29.175 | 1339412894 | 
| 4 | 3422   | NULL   | 1339412899 | 
| 5 | 3422   | NULL   | 1339412906 | 
| 6 | 3422   | NULL   | 1339412906 | 
| 7 | NULL   | 148.23.29.109 | 1339413640 | 
| 8 | NULL   | 148.23.29.109 | 1339413621 | 
| 9 | 5462   | NULL   | 1339414490 | 
| 10 | NULL   | 178.253.29.175 | 1339419901 | 
| 11 | 8007   | NULL   | 1339424860 | 
| 12 | 8007   | NULL   | 1339424822 | 
| 13 | 12353   | NULL   | 1339424902 | 
| . | .    | .    | .   | 
| . | .    | .    | .   | 
| . | .    | .    | .   | 
+----+----------------+----------------+-------------+ 

Auch habe ich diese Tabelle:

// per_days 
+----+---------+--------------+----------------+-----------------+--------------+ 
| id | user_id | AllVisited | MaxConsecutive | LastConsecutive | request_numb | 
+----+---------+--------------+----------------+-----------------+--------------+ 
| 1 | 12353 | 43   | 8    | 3    | 47   | 
| 2 | 3422 | 530   | 130   | 32    | 100   | 
| . | .  | .   | .    | .    | .   | 
| . | .  | .   | .    | .    | .   | 
| . | .  | .   | .    | .    | .   | 
+----+---------+--------------+----------------+-----------------+--------------+ 
-- each user has one row into this^table (I mean user_id column is unique) 

Ich brauche eine Abfrage alle Zeilen aus requests Tabelle auszuwählen, die in den letzten Tag (I Diese Abfrage wird jeden Tag von einem Ereignis ausgeführt und aktualisiert dann alle Zeilen der per_days Tabelle (für jeden Benutzer separat). Etwas wie dieses:

UPDATE 
    per_days AS p 
JOIN requests AS r 
ON p.user_id = r.user_id 
SET p.AllVisited  = p.AllVisited + IF(/* there is a row */, 1, 0), 
    p.MaxConsecutive = IF(p.LastConsecutive > p.MaxConsecutive, LastConsecutive, MaxConsecutive),  
    p.LastConsecutive = IF(/* there is a row */, p.LastConsecutive + 1, 1), 
    p.request_numb = { /* count(1) - the number of all requests (all selected rows) for specific user in this day */ } 
WHERE r.unix_time > subdate(now(), interval '1' day) 

Wie kann ich meine Frage reparieren?

+0

Das erste Problem ist, dass Sie eine JOIN-Anweisung haben, aber nicht tatsächlich die Verbindung der beiden Tabellen zusammen. (Iepuser_id = r.user_id) Vielleicht wäre es einfacher, durch das Brechen der Update-Anweisung in 4 separate Update-Anweisungen zu starten . Anschließend können Sie die Verknüpfungen und Bedingungen für jede Metrik erstellen. Dann versuche später, es zu einem einzigen UPDATE zu machen. –

+0

@RickS Guter Punkt, habe ich bearbeitet. – stack

+0

Sie brauchen nicht das erste 'IF'. Wenn es keine passende Zeile gibt, wird nichts zusammengefügt. – Barmar

Antwort

2

Verknüpfen Sie mit einer Unterabfrage, die alle Benutzer-IDs in requests im Zeitbereich zurückgibt. Verwenden Sie LEFT JOIN, und dann wird Ihr if there's a row Test wird r.user_id IS NOT NULL.

UPDATE 
    per_days AS p 
LEFT JOIN (
    SELECT DISTINCT user_id 
    FROM requests 
    WHERE unix_time > subdate(now(), interval '1' day)) AS r 
ON p.user_id = r.user_id 
SET p.AllVisited  = p.AllVisited + IF(r.user_id IS NOT NULL, 1, 0), 
    p.MaxConsecutive = IF(p.LastConsecutive > p.MaxConsecutive, LastConsecutive, MaxConsecutive),  
    p.LastConsecutive = IF(r.user_id IS NOT NULL, p.LastConsecutive + 1, 1) 
+0

Danke .. upvote. Weißt du was "AllVisited" sein soll? Das ist "++" pro Tag, wenn der Benutzer an diesem Tag aktiv ist. Also denke ich, dass 'p.AllVisited + IFNULL (r.count, 0)' 'p.AllVisited + IF (r.count, 1, 0)' sein sollte. Habe ich recht? – stack

+0

Ihr ursprünglicher Code wurde mit jeder Zeile verknüpft und nicht gruppiert. Daher dachte ich, dass Sie 1 für jede übereinstimmende Zeile hinzufügen möchten. – Barmar

+0

Und meine letzte Frage: eigentlich interessiere ich mich nicht für 'request_numb' Spalte und ich kann es ignorieren * (weil es scheint, dass es einen weiteren Join benötigt, nur um die Zeilen zu zählen) *. Also können Sie bitte Ihre Anfrage hinzufügen, ohne an der 'request_numb' Spalte zu arbeiten? Angenommen, es gibt überhaupt kein 'request_numb'. – stack

Verwandte Themen