我见过许多与此类似的问题,但并不完全像这样。 我需要做的是LEFT JOIN记录,到右表上的前一个记录。例如:
LEFT TABLE 'PROD':
idMachine |production | prod.date
1 |10 | 2016-05-02
2 |11 | 2016-05-15
3 |14 | 2016-06-01
3 |13 | 2016-06-15
RIGHT TABLE 'CONFIG':
idMachine | sett | config.date
1 | 30 | 2016-04-01
2 | 25 | 2016-04-01
3 | 20 | 2016-04-01
1 | 40 | 2016-05-01
3 | 45 | 2016-06-10
1 | 50 | 2016-06-15
and the result should be:
idMachine |production | sett | prod.date
1 |10 | 40 | 2016-05-02
2 |11 | 25 | 2016-05-15
3 |14 | 20 | 2016-06-01
3 |13 | 45 | 2016-06-15
系统就像这样工作,我在机器上记录所有生产运行,并且我记录每台机器配置的每一个变化,我需要知道的是它对生产运行的设置。 如果您在结果中注意到机器1和3,则不会对配置的LATEST记录进行连接,而是在生产发生之前对LAST记录进行连接,这样我们就可以知道我们使用什么设置生成了什么。
我已尝试与JOIN CONFIGS ON prod.date > config.date
加入,但它加入了以前的每个配置,而不仅仅是最后一个。如果我使用LIMIT,它不会给我所需的所有记录。
我已尝试使用MAX对子查询进行一些JOINS,但子查询只返回最新的配置,而不是之前的配置,所以“旧”运行没有配置...
非常感谢任何帮助!!!
答案 0 :(得分:1)
子查询还需要是两个表的JOIN,以允许您在每个PROD的CONFIG中获取前一个日期。然后再将该子查询包含在与表的连接中,以查找sett
值。
这样的事情:
SELECT p2.idMachine, p2.production, c2.sett, p2.date
FROM PROD AS p2
INNER JOIN
(SELECT p.idMachine, p.`date` AS prodDate, MAX(c.`date`) AS prev
FROM PROD AS p
INNER JOIN CONFIG AS c
ON p.idMachine = c.idMachine AND p.`date` >= c.`date`
GROUP BY p.idMachine, prodDate
) AS prevs
ON p2.idMachine = prevs.idMachine AND p2.`date` = prevs.prodDate
INNER JOIN CONFIG AS c2
ON prevs.idMachine = c2.idMachine AND prevs.prev = c2.`date`
如果你有一个WHERE
子句来过滤你关心的PROD记录,你可能想把它放在子查询和主查询中......等一下......
取决于您的数据的形状"塑造"这个版本少了一个连接可以更好。
SELECT p2.idMachine, p2.production, c2.sett, p2.date
FROM (SELECT p.idMachine, p.production, p.`date`, MAX(c.`date`) AS prevConfigDate
FROM PROD AS p
INNER JOIN CONFIG AS c
ON p.idMachine = c.idMachine AND p.`date` >= c.`date`
GROUP BY p.idMachine, p.production, p.`date`
) AS p2
INNER JOIN CONFIG AS c2
ON p2.idMachine = c2.idMachine AND p2.prevConfigDate = c2.`date`
但是,这里的子查询计算每个PROD的MAX,而不是每个(idMachine,date);所以它可能比额外的加入花费更多。但在这种情况下,不需要冗余的WHERE
子句(子查询中只有一个副本)。
我去了...还有一个相关的子查询版本,虽然我不喜欢它们......
SELECT p.*
, (SELECT sett
FROM CONFIG AS c
WHERE c.idMachine = p.idMachine
AND c.date <= p.date
ORDER BY c.date DESC LIMIT 1
) AS sett
FROM PROD AS p
;
另请注意,在所有这些中,我将日期与>=
或<=
进行了比较,而不是<
或>
;您可能需要根据实际数据/逻辑进行调整。
答案 1 :(得分:0)
使用您的数据和工作进行测试
SELECT *
FROM PROD
LEFT JOIN (
SELECT *
FROM `CONFIG`
GROUP BY idMachine
ORDER BY `config.date` ASC
) AS CONFIG ON PROD.idMachine = CONFIG.idMachine
WHERE `config.date` <= PROD.`prod.date`
idMachine production prod.date idMachine sett config.date
1 10 2016-05-02 1 40 2016-05-01
2 11 2016-05-15 2 25 2016-04-01
3 14 2016-06-01 3 20 2016-04-01
3 13 2016-06-15 3 20 2016-04-01