Mysql 显示包含最新编辑版本的所有记录
我有一个包含学生姓名的表,自动增加Mysql 显示包含最新编辑版本的所有记录,mysql,sql,group-by,max,Mysql,Sql,Group By,Max,我有一个包含学生姓名的表,自动增加NR记录,但在每次编辑记录时,都会创建一个新的表,将NR复制到ID字段。 但是当我尝试在MAX(NR)时对ID记录进行分组时,它会显示该ID的最大编号,但当我请求剩余的rocord时,它不会显示该ID组的最后一条记录在 SELECT MAX(`NR`) AS 'mNr',`NR`,`ID`,`Name1`,`Name3`,`Gender` FROM `Kids` GROUP BY `ID` 这会产生如下结果: mNr NR ID Name1 Na
NR
记录,但在每次编辑记录时,都会创建一个新的表,将NR
复制到ID
字段。
但是当我尝试在MAX(NR
)时对ID记录进行分组时,它会显示该ID的最大编号,但当我请求剩余的rocord时,它不会显示该ID组的最后一条记录在
SELECT MAX(`NR`) AS 'mNr',`NR`,`ID`,`Name1`,`Name3`,`Gender`
FROM `Kids` GROUP BY `ID`
这会产生如下结果:
mNr NR ID Name1 Name3 Gender
252 1 1 Alice Carper f
179 2 2 Dorah Fisher f
189 3 3 Racheal King f
173 4 4 Frank Smith m
192 5 5 Patrick Fay m
305 6 6 Gloria Sing f
299 7 7 Bridget Young f
也许在不知情的情况下,您正在使用MySQL的一个神秘特性。MySQL允许您在聚合查询的
select
语句中包含不在聚合函数中或groupby
子句中的列。引擎为这些列输入任意值
执行所需操作的正确方法是使用联接:
SELECT k.*
FROM `Kids` k join
(select id, max(nr) as maxnr
from kids
group by id
) m
on k.id = m.id and nr = maxnr;
以下是文档中的明确解释:
MySQL扩展了GROUPBY的使用,以便选择列表可以引用
GROUP BY子句中未命名的未聚合列。这意味着
前面的查询在MySQL中是合法的。您可以使用此功能
通过避免不必要的列排序和
分组。但是,这主要是在每个
未在GROUP BY中命名的未聚合列对于每个列都是相同的
小组。服务器可以从每个组中自由选择任何值,因此
除非它们相同,否则选择的值是不确定的。
此外,不能从每个组中选择值
受添加ORDER by子句的影响。结果集的排序
在选择值后发生,并且“排序依据”不影响
服务器选择的每个组中的哪些值
您可以更详细地阅读。尽管@Gordon Linoff的答案在技术上是正确的,但在大型数据集上使用可能会耗费更多资源和时间 根据具体情况,我通常会将数据分为两个表
student
和student\u details
,其中
学生的表结构是
CREATE TABLE students (
student_id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT
);
此表的目的是为学生创建一个唯一的编号,并存储您可能不希望保存在修订中的任何其他学生数据
学生详细信息
的表结构为:
CREATE TABLE student_details (
revision_id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
student_id INTEGER NOT NULL,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
gender VARCHAR(1),
is_history BOOLEAN NOT NULL DEFAULT false,
CONSTRAINT FOREIGN KEY(student_id) REFERENCES students(student_id) ON DELETE RESTRICT
);
这个表存储了学生的实际数据。更新某个学生的数据时,您只需将该学生的记录的is\u history
列更新为true
。然后,在选择学生数据时,只需使用选择学生详细信息。*从学生左侧加入学生详细信息(student\u details.student\u id=students.student\u id和student\u details.is\u history=false)
。这将始终返回学生详细信息的最新版本
插入新学员
插入学生
插入学生(学生id)值(“”)代码>
获取最后一个插入id
选择最后一个插入id()代码>(在本例中,假设它返回1)
插入学生详细信息
插入学生详细信息(学生id、名、姓、性别)值('1','Alice','Carper','f')
更新现有学生(假设学生id=1)
将所有以前的学生详细信息“修订”设置为“历史记录”:
更新学生详细信息设置为“历史记录=真”,其中学生详细信息。学生id=1,且为“历史记录=假”
添加新版本:
在学生详细信息(学生id、名、姓、性别)中插入值('1'、'Alice'、'Achand'、'f')
获取学生及其最新学生详细信息
选择student\u details.*从students LEFT开始加入student\u details ON(student\u details.student\u id=students.student\u id和student\u details.is\u history=false)
您能否按原样显示示例数据以及查询所需的结果?现在还不清楚你想要达到什么目标。太好了,它奏效了!在过去的三天里,我一直在努力解决这个问题。你是一个活生生的储蓄者;-)@用户2811590如果您认为这是正确答案,请向上投票并将其标记为正确:)
CREATE TABLE student_details (
revision_id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
student_id INTEGER NOT NULL,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
gender VARCHAR(1),
is_history BOOLEAN NOT NULL DEFAULT false,
CONSTRAINT FOREIGN KEY(student_id) REFERENCES students(student_id) ON DELETE RESTRICT
);