Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 显示包含最新编辑版本的所有记录_Mysql_Sql_Group By_Max - Fatal编程技术网

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
    );