更新SQL(SQLite)中某个值的最新版本

更新SQL(SQLite)中某个值的最新版本,sql,sqlite,Sql,Sqlite,我目前正在解决一个问题,我有一个不雅观的解决方案。我将一条记录的多个版本存储在一个表中。一个很好的例子是文档的版本。一个文档有多个条目。我有一个名为code的列,它存储文档特有的ID。每行还有一个Active字段(布尔值),指示记录是“活动”(最新版本)还是“非活动”。在这种情况下,只有最新版本可以激活。我这样做是为了方便查询数据(而不是获取每个文档的顶部) 我的数据可能如下所示: Code Active VersionNo ABYY 0 1 R

我目前正在解决一个问题,我有一个不雅观的解决方案。我将一条记录的多个版本存储在一个表中。一个很好的例子是文档的版本。一个文档有多个条目。我有一个名为
code
的列,它存储文档特有的ID。每行还有一个
Active
字段(布尔值),指示记录是“活动”(最新版本)还是“非活动”。在这种情况下,只有最新版本可以激活。我这样做是为了方便查询数据(而不是获取每个文档的顶部)

我的数据可能如下所示:

Code        Active    VersionNo
ABYY        0         1
RRUP        0         1
RRUP        0         2
ABYY        0         2
ABYY        0         3
ABYY        1         4
RRUP        1         3
我的问题是,当我删除一条记录时,我希望确保文档中有一条记录(最新的一条)标记为活动。以下是三种情况:

  • 我删除了文件ABYY的第4版-我想激活该文件的第3版
  • 我删除了文件ABYY的版本3-我想确保版本4仍然标记为活动
  • (棘手的一个)我删除了ABYY文件的第3版。后来我决定删除第4版我希望版本2被标记为活动,这意味着您不能从版本号中减去1
  • 与基于特定数据创建复杂查询不同,我更愿意创建一个通用查询,将所有文档的活动字段设置为0,但版本号最高的文档除外,它将改为1。通过这种方式,如果我不确定某个特定文档的数据,我可以将同一查询重新用作“清理”脚本

    现在我有两个问题,第二个问题有点长。以下是我的工作:

    UPDATE documents
    SET Active = 0
    WHERE Code = 'ABYY';
    
    UPDATE documents u
    SET Active = 1
    WHERE id = (SELECT TOP 1 id
                FROM documents
                WHERE Code = 'ABYY'
                ORDER BY VersionNo DESC);
    

    我是否可以将这些查询折叠成一个查询(最好也更简单)?我是为SQLite(最新版本)写这篇文章的。

    您不能折叠查询,至少不能折叠它们的编写方式,因为在第一个更新查询中,您设置了“Active=0”,而在另一个更新查询中,您设置了“Active=1”

    如果要将所有这些“活动”字段保存为0,可以执行以下操作:

    UPDATE documents
    SET Active = 0
    WHERE Code = 'ABYY' && Active = 1;
    

    这应该使得只有当前使用该代码的活动记录被更改,而不是所有使用该代码的记录(甚至那些已经处于活动状态的记录=0)。

    您不能折叠查询,至少不能折叠它们的编写方式,因为在第一个更新查询中,您设置了“活动=0”,而在另一个查询中设置了“活动=1”

    如果要将所有这些“活动”字段保存为0,可以执行以下操作:

    UPDATE documents
    SET Active = 0
    WHERE Code = 'ABYY' && Active = 1;
    
    这应使其仅更改具有该代码的当前活动记录,而不是更改具有该代码的所有记录(即使那些已处于活动状态的记录=0)。

    请尝试:

    UPDATE DOCUMENTS
       SET active = CASE 
                      WHEN id = (SELECT d.id
                                   FROM DOCUMENTS d
                                  WHERE d.code = DOCUMENTS.code
                               ORDER BY d.versionno DESC
                                  LIMIT 1) THEN 1
                      ELSE 0
                    END
     WHERE code = 'ABYY'
    
    尝试:

    这应该做到:

    UPDATE TheTable 
    SET Active=(VersionNo=(SELECT MAX(VersionNo)
                           FROM TheTable AS T1
                           WHERE T1.code=TheTable.code)) 
    WHERE code='RRUP'
    
    另外,要规范化整个表,只需从外部更新中删除where子句:

    UPDATE TheTable 
    SET Active=(VersionNo=(SELECT MAX(VersionNo)
                           FROM TheTable AS T1
                           WHERE T1.code=TheTable.code)) 
    
    这应该做到:

    UPDATE TheTable 
    SET Active=(VersionNo=(SELECT MAX(VersionNo)
                           FROM TheTable AS T1
                           WHERE T1.code=TheTable.code)) 
    WHERE code='RRUP'
    
    另外,要规范化整个表,只需从外部更新中删除where子句:

    UPDATE TheTable 
    SET Active=(VersionNo=(SELECT MAX(VersionNo)
                           FROM TheTable AS T1
                           WHERE T1.code=TheTable.code)) 
    

    我认为这不是一个好的设计。您可能认为存储活动标志是在简化您的生活,但现在的问题表明,没有免费的午餐,无论您通过不使用最新版本的Date获取最新版本的文档而节省了多少精力,您都是在别处付费。我将去掉该标志,并基于versiondate实现该规则。如果想忽略某个版本,可以将其标记为“已删除”。我认为这不是一个好的设计。您可能认为存储活动标志是在简化您的生活,但现在的问题表明,没有免费的午餐,无论您通过不使用最新版本的Date获取最新版本的文档而节省了多少精力,您都是在别处付费。我将去掉该标志,并基于versiondate实现该规则。如果要忽略某个版本,可以将其标记为“已删除”。我试图做的是确保所有其他项目都标记为零。如果是在一个查询中完成的,您可以说“每隔一项”,但如果是在两个查询中完成的,您真的不能。这就是为什么我将所有项都标记为零,然后在第二个查询中,我将正确的项标记为一对一。我试图做的是确保所有其他项都标记为零。如果是在一个查询中完成的,您可以说“每隔一项”,但如果是在两个查询中完成的,您真的不能。这就是为什么我将所有内容都标记为零,然后在第二个查询中,我将正确的1标记为1。