我正在构建一个可以与手机同步的版本系统 例如,手机在版本1和服务器上运行 有版本2,所以这意味着服务器将返回 版本2的数据。
我有以下表格:
CREATE TABLE `exercise` (
`id_exercise` int(11) NOT NULL,
`name` varchar(45) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `exercise_audit` (
`id_exercise_audit` int(11) NOT NULL,
`name` varchar(45) NOT NULL COMMENT 'The name will take the new value if inserted ,or the old value if edited.And the latest value if deleted.',
`action_peformed` varchar(45) NOT NULL,
`version` int(11) NOT NULL,
`reference_id` int(11) NOT NULL,
`change_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `version` (
`id_version` int(11) NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`state` enum('C','P') NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
练习表有3个不同的触发器,因此它可以处理exercise_audit表。
我对以下查询的当前回复
SELECT ea.action_peformed,
ea.version,
ea.change_date,
e.name,
e.id_exercise
FROM exercise_audit AS ea
LEFT JOIN exercise AS e
ON e.id_exercise = ea.reference_id
WHERE version > :version
看起来像这样:
[
{
"action_peformed": "insert",
"version": "1",
"change_date": "2017-06-22 16:42:03",
"audit_name": "Push Ups",
"current_name": "Push Ups",
"id_exercise": "1"
},
{
"action_peformed": "insert",
"version": "1",
"change_date": "2017-06-22 16:42:06",
"audit_name": "Squat",
"current_name": "Squat",
"id_exercise": "2"
},
{
"action_peformed": "insert",
"version": "1",
"change_date": "2017-06-22 16:42:09",
"audit_name": "Chin Ups",
"current_name": "Chin Ups",
"id_exercise": "3"
},
{
"action_peformed": "insert",
"version": "2",
"change_date": "2017-06-22 16:44:25",
"audit_name": "Pull Ups",
"current_name": "Pull Ups",
"id_exercise": "4"
},
{
"action_peformed": "insert",
"version": "2",
"change_date": "2017-06-22 16:45:08",
"audit_name": "Sit Up",
"current_name": "Sit Up",
"id_exercise": "5"
},
{
"action_peformed": "insert",
"version": "2",
"change_date": "2017-06-22 16:45:28",
"audit_name": "Pike Push Up",
"current_name": "Pike Push Ups",
"id_exercise": "6"
},
{
"action_peformed": "update",
"version": "3",
"change_date": "2017-06-22 16:47:28",
"audit_name": "Pike Push Up",
"current_name": "Pike Push Ups",
"id_exercise": "6"
}
问题在于这一部分:
{
"action_peformed": "insert",
"version": "2",
"change_date": "2017-06-22 16:45:28",
"audit_name": "Pike Push Up",
"current_name": "Pike Push Ups",
"id_exercise": "6"
},
{
"action_peformed": "update",
"version": "3",
"change_date": "2017-06-22 16:47:28",
"audit_name": "Pike Push Up",
"current_name": "Pike Push Ups",
"id_exercise": "6"
}
请注意!名称在两者中相同的原因是因为在插入中 name是NEW.name,在更新中名称是OLD.name,所以我可以 跟踪历史数据。
正如您所看到的,我在id_exercise为6的情况下进行了同样的练习,它已插入版本2并在版本3中更新。
我的问题是如何在sql中将它们组合在一起。
例如,要实现以下目标:
{
"action_peformed": "insert",
"version": "3",
"change_date": "2017-06-22 16:47:28",
"audit_name": "Pike Push Up",
"current_name": "Pike Push Ups",
"id_exercise": "6"
}
它结合了更新和插入,以便它使用最后更新的数据作为插入数据。
原因是用户在移动设备上有版本1,并且他暂时没有与网络同步。例如,网络版本为6,版本中添加了练习3,它也在版本6中更新。所以当手机请求数据时它不会插入和更新同一件事。而不是将它组合成一个具有最新值的东西作为插入而不是更新
我可以用一些PHP代码解决它,但它会让它自我复杂......
答案 0 :(得分:1)
不确定是什么决定了action_performed的值,因此该部分是猜测。
SELECT IF('insert' IN GROUP_CONCAT(ea.`action_peformed`),'insert','update') as `action_performed`,
MAX(ea.`version`) as `version`,
MAX(ea.`change_date`) as `change_date`,
e.`name`,
e.`id_exercise`
FROM `exercise_audit` AS ea
LEFT JOIN `exercise` AS e
ON e.`id_exercise` = ea.`reference_id`
WHERE `version` > :version
GROUP BY e.`id_exercise`