2016-07-28 11 views
0

私はMySQL(5.7)を使用しています。IDとタイムスタンプの2つのテーブルベースを結合したいと考えています。MySQL JOIN不規則テーブル

私のテーブルは次のようになります。

プライマリ表:

+--------+---------------------+-------------+ 
| 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 | 
+--------+---------------------+-------------+ 

セカンダリ表:私は何をしたいか

+--------+---------------------+-------------+ 
| 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 | 
+--------+---------------------+-------------+ 

は(プライマリとセカンダリの両方のテーブルから)すべてのレコードを返すことです。レコードが1つまたは他のテーブルに存在しない場合は、nullを返します。

各テーブルのレコードは、異なる時間間隔で入力できます。

私が使用しているクエリは次のとおりです。

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 

これが返されます。

+--------+---------------------+---------------------+-----------------------+ 
| 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 | 
+--------+---------------------+---------------------+-----------------------+ 

これは、むしろそれらをマージするよりも、重複したタイムスタンプを返します。

私はそれを返すために必要な方法は、次のようになります。誰かがこのために正しい方向に私を指すしてもらえ

+--------+---------------------+---------------------+-----------------------+ 
| 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 | 
+--------+---------------------+---------------------+-----------------------+ 

ありがとう:)

+0

.....私はそれをもっとされるべきだと思うものです。セカンダリテーブルはプライマリのすべてのタイムスタンプをカバーしていますか? – 1000111

+0

私は運がない別のJOINで遊んでいました。 タイムスタンプは2つのテーブルの間で一致する可能性がありますが、一致する必要はありません –

答えて

0

それぞれのクエリの行が異なるため、すべてを取得しています。

プライマリとセカンダリの情報を使わずに同じクエリを実行すると、別個のユーザー/タイムスタンプが得られます。

次にLEFTをプライマリに結合し、UserIdとTimeStampをセカンダリに結合します。

このような何か.....また

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 

、私はあなたがここに集約を行っていないとして、あなたはGROUP BYを必要としないと思います。おそらくあなたはそれをORDER BYと混同しています。 また、WHEREを移動して、JOINSの直後に1回だけ持っているかもしれませんが、あなたが理由のために持っているようにしている可能性があります。

しかし、とにかく、ここで私はuが代わりに労働組合の参加を左必要があると思います

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

2番目のブロックは少し遅く見えましたが、最初は完全に機能しました。そしてGROUP BYは必要ありません –

+0

私はそれをストアドプロシージャに入れて呼び出します。 ProceはUserId、StartDate、およびEndDateを取ります。 遅かれ早かれ、タイプミスを行い、それ以外の場合は不一致のパラメータを入れます。 喜んで助けました;) – AntDC