我正在尝试从时间戳中的两个表A和B中连接数据.理想情况下,我希望tableA的每一行都满足unitCode和时间约束,如果tableB中有一个关联的行,则加入它,否则假设表B中的coloumns已连接但是为null或为空.
假设TableA看起来像这样:
id | 时间戳| itemA1 | itemA2 | itemA3
和TableB看起来像这样:
id | 时间戳| itemB1 | itemB2
所以数据可能如下所示:
目前我正在使用这个:
SELECT * FROM tableA AS a JOIN (SELECT * FROM tableB) AS b ON (a.timestamp = b.timestamp) WHERE b.unitCode = 'CODE' AND b.timestamp BETWEEN 'STARTDATETIME' AND 'ENDDATETIME' ORDER BY b.timestamp DESC`
但是它只会从给定tableA的对应tableB的实例中产生行.
用一个LEFT JOIN.A LEFT JOIN获取条件语句左侧的所有记录,以及右侧适用的所有记录.但是,您需要在WHERE子句中小心,因为如果它对您的右表有一个值限制(在您的情况表'b'中),那么它仍将排除这些行.
SELECT * FROM tableA AS a
LEFT JOIN (SELECT * FROM tableB) AS b
ON (a.timestamp = b.timestamp)
WHERE b.unitCode = 'CODE' AND b.timestamp BETWEEN 'STARTDATETIME' AND 'ENDDATETIME' ORDER BY b.timestamp DESC`
Run Code Online (Sandbox Code Playgroud)
LEFT JOIN参考:https:
//dev.mysql.com/doc/refman/5.7/en/left-join-optimization.html
正如@Ike指出的那样,您的查询可以更正为:
SELECT *
FROM tableA AS a
LEFT JOIN tableB AS b
ON a.timestamp = b.timestamp
AND b.unitCode = 'CODE'
AND b.timestamp BETWEEN 'STARTDATETIME' AND 'ENDDATETIME'
ORDER BY b.timestamp DESC`
Run Code Online (Sandbox Code Playgroud)
因为正如我前面提到的,如果条件在WHERE子句中,它将排除概念,LEFT JOIN因此所有具有NULL值的行(因为它不符合表b的标准)将被排除.
为了解决你的评论,如果你添加了WHERE条款,我建议(基于我对你的目标的理解)只有条件影响tableA并且具有tableB的所有条件LEFT JOIN.
SELECT *
FROM tableA AS a
LEFT JOIN tableB AS b
ON a.timestamp = b.timestamp
AND b.unitCode = 'CODE'
AND b.timestamp BETWEEN 'STARTDATETIME' AND 'ENDDATETIME'
WHERE
a.timestamp BETWEEN 'STARTDATETIME' AND 'ENDDATETIME'
ORDER BY b.timestamp DESC`
Run Code Online (Sandbox Code Playgroud)
现在,如果a.timestamp条件是您正在寻找的,那么tableB中的条件LEFT JOIN是多余的,因为我们已经知道tableB中的时间戳必须与tableA中的相应时间戳匹配.