2016-07-28 45 views
0

我正在使用MySQL(5.7),我想加入2个表的基础上一个ID和时间戳。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 | 
+--------+---------------------+-------------+ 

我想要做的是返回所有记录(从一级和二级表) 。如果记录不存在于一个或另一个表中,它将返回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,没有运气。 时间戳可以但不一定匹配在两张表之间 –

回答

0

你让他们都因为在每个查询行是不同的。

你可以运行相同的查询,但没有中小学信息,并且会给你不同的用户/时间戳。

然后LEFT加入到UserId和TimeStamp上的Primary和Secondary。

像这样的东西.....

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之后有一次,但也许你已经完成了它,就像你有一个原因。

但无论如何,这是我认为它应该更像.....

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

第二个块看起来有点慢,但第一个块完美运行。并不需要GROUP BY –

+0

我把它放在存储过程中并调用它。 Proce将采用UserId,StartDate和EndDate。 迟早你会做一个错字,然后输入不匹配的参数。 很高兴我帮了忙;) – AntDC