2016-07-28 10 views
0

Ich benutze MySQL (5.7), und ich möchte 2 Tabellen Basen auf einer ID und Timestamp verbinden.MySQL JOIN unregelmäßige Tabellen

Meine Tabellen wie folgt aussehen:

Primary Table:

+--------+---------------------+-------------+ 
| UserId | Timestamp   | Information | 
+--------+---------------------+-------------+ 
|  5 | 2015-11-29 11:15:00 |   1 | 
|  5 | 2015-11-29 11:30:00 |   1 | 
|  5 | 2015-11-29 11:45:00 |   1 | 
|  5 | 2015-11-29 12:00:00 |   1 | 
|  5 | 2015-11-29 12:16:00 |   1 | 
+--------+---------------------+-------------+ 

Secondary Tabelle:

+--------+---------------------+-------------+ 
| UserId | Timestamp   | Information | 
+--------+---------------------+-------------+ 
|  5 | 2015-11-29 11:00:00 |   2 | 
|  5 | 2015-11-29 11:30:00 |   2 | 
|  5 | 2015-11-29 11:45:00 |   2 | 
|  5 | 2015-11-29 12:00:00 |   2 | 
|  5 | 2015-11-29 12:01:00 |   2 | 
|  5 | 2015-11-29 12:02:00 |   2 | 
|  5 | 2015-11-29 12:03:00 |   2 | 
|  5 | 2015-11-29 12:04:00 |   2 | 
|  5 | 2015-11-29 12:05:00 |   2 | 
|  5 | 2015-11-29 12:06:00 |   2 | 
|  5 | 2015-11-29 12:07:00 |   2 | 
|  5 | 2015-11-29 12:10:00 |   2 | 
|  5 | 2015-11-29 12:15:00 |   2 | 
|  5 | 2015-11-29 12:16:00 |   2 | 
+--------+---------------------+-------------+ 

Was ich alle Datensätze tun möchte, ist das Rück (von primären und sekundären Tabellen) . Wenn der Datensatz in der einen oder anderen Tabelle nicht vorhanden ist, wird null zurückgegeben.

Die Datensätze in jeder Tabelle können in unterschiedlichen Zeitintervallen eingehen.

Die Abfrage, die ich benutze ist:

SELECT UserId, Timestamp, PrimaryInformation, SecondaryInformation 
FROM (
    SELECT 
     UserId, 
     Timestamp 
     Information AS PrimaryInformation, 
     null AS SecondaryInformation 
    FROM Primary 
    WHERE UserId = 5 AND Timestamp BETWEEN '2015-11-29 11:00:00' AND '2015-11-29 12:20:00' 

    UNION 

    SELECT 
     UserId, 
     Timestamp 
     null AS PrimaryInformation, 
     Information AS SecondaryInformation 
    FROM Secondary 
    WHERE UserId = 5 AND Timestamp BETWEEN '2015-11-29 11:00:00' AND '2015-11-29 12:20:00' 
) t 
GROUP BY UserId, Timestamp, PrimaryInformation, SecondaryInformation 

Das gibt:

+--------+---------------------+---------------------+-----------------------+ 
| UserId | Timestamp   | Primary Information | Secondary Information | 
+--------+---------------------+---------------------+-----------------------+ 
|  5 | 2015-11-29 11:00:00 |    null |      2 | 
|  5 | 2015-11-29 11:15:00 |     1 |     null | 
|  5 | 2015-11-29 11:30:00 |     1 |     null | 
|  5 | 2015-11-29 11:30:00 |    null |      2 | 
|  5 | 2015-11-29 11:45:00 |     1 |     null | 
|  5 | 2015-11-29 11:45:00 |    null |      2 | 
|  5 | 2015-11-29 12:00:00 |     1 |     null | 
|  5 | 2015-11-29 12:00:00 |    null |      2 | 
|  5 | 2015-11-29 12:01:00 |    null |      2 | 
|  5 | 2015-11-29 12:02:00 |    null |      2 | 
|  5 | 2015-11-29 12:03:00 |    null |      2 | 
|  5 | 2015-11-29 12:04:00 |    null |      2 | 
|  5 | 2015-11-29 12:05:00 |    null |      2 | 
|  5 | 2015-11-29 12:06:00 |    null |      2 | 
|  5 | 2015-11-29 12:07:00 |    null |      2 | 
|  5 | 2015-11-29 12:10:00 |    null |      2 | 
|  5 | 2015-11-29 12:15:00 |    null |      2 | 
|  5 | 2015-11-29 12:16:00 |     1 |     null | 
|  5 | 2015-11-29 12:16:00 |    null |      2 | 
+--------+---------------------+---------------------+-----------------------+ 

Diese duplizierten Zeitstempel zurück, anstatt sie zu verschmelzen.

Die Art und Weise, dass ich es brauchen würde zurückkehren wie folgt aussehen:

+--------+---------------------+---------------------+-----------------------+ 
| UserId | Timestamp   | PrimaryInformation | SecondaryInformation | 
+--------+---------------------+---------------------+-----------------------+ 
|  5 | 2015-11-29 11:00:00 |    null |      2 | 
|  5 | 2015-11-29 11:15:00 |     1 |     null | 
|  5 | 2015-11-29 11:30:00 |     1 |      2 | 
|  5 | 2015-11-29 11:45:00 |     1 |      2 | 
|  5 | 2015-11-29 12:00:00 |     1 |      2 | 
|  5 | 2015-11-29 12:01:00 |    null |      2 | 
|  5 | 2015-11-29 12:02:00 |    null |      2 | 
|  5 | 2015-11-29 12:03:00 |    null |      2 | 
|  5 | 2015-11-29 12:04:00 |    null |      2 | 
|  5 | 2015-11-29 12:05:00 |    null |      2 | 
|  5 | 2015-11-29 12:06:00 |    null |      2 | 
|  5 | 2015-11-29 12:07:00 |    null |      2 | 
|  5 | 2015-11-29 12:10:00 |    null |      2 | 
|  5 | 2015-11-29 12:15:00 |    null |      2 | 
|  5 | 2015-11-29 12:16:00 |     1 |      2 | 
+--------+---------------------+---------------------+-----------------------+ 

Könnte jemand bitte diese mich in die richtige Richtung für Punkt.

Thanks :)

+0

I u links müssen erraten beitreten statt Vereinigung. Umfasst die Sekundärtabelle alle Zeitstempel in der Primärdatenbank? – 1000111

+0

Ich hatte ein Spiel mit verschiedenen JOINs ohne Glück. Die Zeitstempel konnten, aber nicht unbedingt übereinstimmen zwischen den 2 Tabellen –

Antwort

0

Sie erhalten sie alle, weil die Zeilen in jeder Abfrage verschieden sind.

Sie könnten die gleiche Abfrage ausführen, aber ohne primäre und sekundäre Informationen und das gibt Ihnen den eindeutigen Benutzer/Timestamp.

Dann LINKE Beitritt zu Primary und sekundäre auf UserId und TimeStamp.

So etwas .....

SELECT UserId, Timestamp, P.PrimaryInformation, S.SecondaryInformation 
FROM (
    SELECT 
     UserId, 
     Timestamp 
    FROM Primary 
    WHERE UserId = 5 AND Timestamp BETWEEN '2015-11-29 11:00:00' AND '2015-11-29 12:20:00' 

    UNION 

    SELECT 
     UserId, 
     Timestamp 
    FROM Secondary 
    WHERE UserId = 5 AND Timestamp BETWEEN '2015-11-29 11:00:00' AND '2015-11-29 12:20:00' 
) t 
LEFT OUTER JOIN Primary P ON P.UserId = t.UserId and P.Timestamp = t.TimeStamp 
LEFT OUTER JOIN Secondary S ON S.UserId = t.UserId and S.Timestamp = t.TimeStamp 
GROUP BY UserId, Timestamp, PrimaryInformation, SecondaryInformation 

Auch ich glaube nicht, dass Sie die GROUP BY müssen wie jede Aggregation hier nicht tun werden. Vielleicht hast du es mit ORDER BY durcheinander gebracht. Sie könnten auch die WHERE verschieben und nur einmal nach den JOINS haben, aber vielleicht haben Sie es so gemacht, wie Sie es aus einem bestimmten Grund getan haben.

Aber trotzdem, hier ist was ich denke, es wie mehr sein sollte .....

SELECT UserId, Timestamp, P.PrimaryInformation, S.SecondaryInformation 
FROM (
    SELECT 
     UserId, 
     Timestamp 
    FROM Primary 
    UNION 
    SELECT 
     UserId, 
     Timestamp 
    FROM Secondary 
) t 
LEFT OUTER JOIN Primary P ON P.UserId = t.UserId and P.Timestamp = t.TimeStamp 
LEFT OUTER JOIN Secondary S ON S.UserId = t.UserId and S.Timestamp = t.TimeStamp 
WHERE 
    t.UserId = 5 AND t.Timestamp BETWEEN '2015-11-29 11:00:00' AND '2015-11-29 12:20:00' 
ORDER BY 
    UserId, Timestamp, PrimaryInformation, SecondaryInformation 
+0

Der zweite Block schien ein bisschen langsam, aber der erste funktionierte perfekt. Und GROUP BY wurde nicht benötigt –

+0

Ich würde es in eine gespeicherte Prozedur legen und das anrufen. Proce würde UserId, StartDate und EndDate übernehmen. Früher oder später werden Sie einen Tippfehler machen und sonst nicht übereinstimmende Parameter eingeben. Froh, dass ich geholfen habe;) – AntDC