sql - 获取与历史上某个时间点的应用程序状态相对应的行
问题描述
我不确定如何用语言来描述我的问题,所以我创建了一个插图来提供帮助。
|-------------------------------------------|
| version_table (many-to-many) |
|-------------------------------------------|
| version_id | a_id | b_id | operation_type |
|------------|------|------|----------------|
| 1 | 1 | 1 | INSERT |
| 1 | 1 | 2 | INSERT |
| 2 | 1 | 1 | DELETE |
| 3 | 1 | 2 | DELETE |
|------------|------|------|----------------|
在此表中查询每个版本会产生以下结果:
- 版本 1 应该返回两行(因为插入很明显)。
- 版本 2 应该返回一行(不太明显,但在调用 DELETE 操作之前该行存在)。
- 版本 3 应该返回零行(之前的 DELETE 操作清除的所有行)。
很明显,我们需要获取在提供的版本之前或之上插入的所有行。
WHERE table.version_id <= :VERSION
但不明显的是我们如何排除已“删除”的行。
AND table.version_id > alias.version_id AND alias.operation_type = "DELETE"
这是我最终写的查询:
SELECT tag.id AS tag_id, tag.name AS tag_name
FROM tag
JOIN article_tag_version ON article_tag_version.tag_id = tag.id
LEFT OUTER JOIN article_tag_version AS article_tag_version_1 ON
article_tag_version_1.tag_id = tag.id AND
article_tag_version_1.operation_type = "DELETE"
WHERE article_tag_version.version_id <= ? AND article_tag_version.version_id > article_tag_version_1.version_id
...但它没有以我期望的方式返回结果(没有结果)。
解决方案
您可以检查NOT EXISTS
“事物”(无论它是什么)是否已在它插入的版本和目标版本之间的版本中被删除。
SELECT *
FROM version_table v1
WHERE v1.operation_type = 'INSERT'
AND NOT EXISTS (SELECT *
FROM version_table v2
WHERE v2.version_id >= v1.version_id
AND v2.version_id <= :VERSION
AND (v2.a_id,
v2.b_id) = (v1.a_id,
v1.b_id)
AND v2.operation_type = 'DELETE')
AND v1.version_id <= :VERSION;
推荐阅读
- java - 扩展 `JpaRepository`,但只实现子接口
- java - Feign : 文件上传配置
- c# - 带有 TypedParameter 的 Autofac Resolve 总是首先选择预期的相同类型参数?
- python - 根据odoo中Many2one字段的值更改One2many字段
- java - 如何在片段中获得活动?
- java - 在房间数据库中插入用户时显示错误
- powershell - Defender Preference PowerShell 命令与相应的注册表项不同
- javascript - Angular 与 ngrx - 没有任何事情发生
- vue.js - 尝试导入时出现 Uncaught SyntaxError: Unexpected identifier error
- hadoop - 安全 Hadoop - 在后台启动 Datanode