我一直在困惑这一段时间,并意识到是时候寻求一些帮助了。作为与第三方系统集成的一部分,我向现有系统引入了一个额外的表来管理记录的同步。我会缩小表结构,只包含足够的细节来表示问题:
Table 1: data
Columns: (int)data_id*, (varchar)name, (datetime)date_created
Table 2: sync
Columns: (int)sync_id*, (int)data_id, (int)result, (varchar)details,
(datetime)date_created
* denotes primary index
当第三方系统尝试同步记录时,它使用HTTP GET请求,服务器端脚本返回包含等待第一次同步的记录信息的XML响应(不存在同步记录)此data_id),并且还记录等待在先前尝试失败的同步重试的信息(该data_id的最新同步记录将具有结果值0)。然后,第三方系统对不同的服务器端脚本使用HTTP POST请求,该脚本提供有关哪些记录能够匹配并成功同步(result = 1
)以及哪些记录无法匹配和同步的反馈with(result = 0, details = "Error Message"
)。
每个数据记录经常会有多个同步记录,因为有许多有效的方案可能会阻止成功同步,而用户不会先采取某些措施。
保持记录每个同步尝试非常重要,因此只能将同步列添加到数据表中。
我正在尝试使用SQL的伪代码版本是这样的:
到目前为止,我最近使用的SQL语句使用LEFT JOIN
:
SELECT d.data_id, d.name, d.date_created, s.sync_id, s.result, s.details
FROM (
SELECT data_id, name, date_created
FROM data
) AS d
LEFT JOIN (
SELECT sync_id, data_id, result, details, date_created
FROM sync
GROUP BY data_id
) AS s
ON d.data_id = s.data_id
ORDER BY d.date_created DESC;
不幸的是,这似乎没有采用最新的同步记录,但GROUP BY data_id
似乎只是抓住它找到的第一个同步记录。 MySQL语法不允许我在ORDER BY date_created DESC
行之前放置GROUP BY data_id
。如果我在GROUP BY行之后放置此ORDER BY语句似乎没有效果,并且最新的同步记录不是结果中数据列旁边显示的记录。
我开始使用的更简单的版本具有完全相同的问题,不一定采用最新的同步记录:
SELECT d.data_id, d.name, d.date_created, s.result, s.details
FROM data AS d LEFT JOIN sync AS s ON d.data_id = s.data_id
WHERE s.result = 0 OR s.result IS NULL;
我也尝试使用子查询来实现这一点,同样的问题:
SELECT d.data_id, d.name, d.date_created, s.sync_id, s.result, s.details
FROM (
SELECT data_id, name, date_created
FROM data
) AS d, (
SELECT s.sync_id, s.data_id, s.result, s.details, s.date_created
FROM sync AS s, data AS d
WHERE s.data_id = d.data_id
ORDER BY s.date_created DESC
) AS s
WHERE d.data_id = s.data_id
ORDER BY s.date_created DESC;
请有人建议我如何确保在单个查询中只获取最新的同步记录和数据记录。我很高兴解决方案可以根据需要涉及任何联接或子查询的组合。谢谢。
答案 0 :(得分:2)
有几种方法可以做到这一点。以下是聚合sync
表格以获取每个date_created
记录的最新data_id
的表格:
SELECT d.data_id, d.name, d.date_created, s.result, s.details
FROM data AS d LEFT JOIN
sync AS s
ON d.data_id = s.data_id LEFT JOIN
(select s.data_id, max(date_created) as maxdc
from sync s
group by s.data_id
) smax
on s.data_id = smax.data_id and s.date_created = smax.maxdc
WHERE s.result = 0 OR s.result IS NULL;
答案 1 :(得分:1)
你只需要在你的查询中使用order by for sync table然后分组,因为mysql不支持group by之前的顺序,因为mysql使用第一个组然后按顺序排列。
因此您可以使用以下查询。
SELECT d.data_id, d.name, d.date_created, s.sync_id, s.result, s.details
FROM `data` AS d LEFT JOIN (
SELECT sync_id, data_id, result, details, date_created FROM (
SELECT sync_id, data_id, result, details, date_created
FROM sync
ORDER BY date_created DESC
) a GROUP BY a.data_id
) s
ON d.data_id = s.data_id
ORDER BY d.date_created DESC;