php - 查看最新版本的删除历史记录

标签 php mysql subquery window-functions sql-view

我有这张表:

表 S_TEXT:

PS_TEXT     S_TEXT   VS_TEXT        D_TEXT  
1           1        1              Hey                 
2           1        1              Hello
3           1        2              Oh
4           2        1              Hallo
5           2        1              Hallo
6           2        2              Hi

然后我有这个 View 来删除所有历史记录:

CREATE OR REPLACE VIEW `VHS_TEXT`
AS SELECT 
`S_TEXT`.`PS_TEXT`, 
`S_TEXT`.`S_TEXT`, 
`S_TEXT`.`VS_TEXT`, 
`S_TEXT`.`D_TEXT`
FROM 
`S_TEXT` LEFT JOIN 
`S_TEXT` AS `t2`
ON (
`S_TEXT`.`S_TEXT` = `t2`.`S_TEXT` AND `S_TEXT`.`PS_TEXT` < `t2`.`PS_TEXT`
)
WHERE
`t2`.`PS_TEXT` IS NULL;

查看 VHS_TEXT:

PS_TEXT     S_TEXT  VS_TEXT     D_TEXT  
3           1       2           Oh
6           2       2           Hi

然后我有这个 View 来显示没有双峰的版本:

CREATE OR REPLACE VIEW `VVS_TEXT`
AS SELECT 
`S_TEXT`.`PS_TEXT`, 
`S_TEXT`.`S_TEXT`, 
`S_TEXT`.`VS_TEXT`, 
`S_TEXT`.`D_TEXT`
FROM 
`S_TEXT` LEFT JOIN 
`S_TEXT` AS `t2`
ON (
`S_TEXT`.`S_TEXT` = `t2`.`S_TEXT`
AND `S_TEXT`.`VS_TEXT` = `t2`.`VS_TEXT`
AND `S_TEXT`.`PS_TEXT` < `t2`.`PS_TEXT`
)
WHERE
`t2`.`PS_TEXT` IS NULL;

查看 VVS_TEXT:

PS_TEXT     S_TEXT   VS_TEXT        D_TEXT  
2           1        1              Hello
3           1        2              Oh
5           2        1              Hallo
6           2        2              Hi

现在我插入一个新行实例 2 版本 1:

PS_TEXT     S_TEXT   VS_TEXT        D_TEXT  
1           1        1              Hey                 
2           1        1              Hello
3           1        2              Oh
4           2        1              Hallo
5           2        1              Hallo
6           2        2              Hi
7           2        1              Hi too

现在我在 VHS_TEXT 中得到了这个:

PS_TEXT     S_TEXT  VS_TEXT     D_TEXT  
3           1       2           Oh
7           2       1           Hi too

但我想要这个:

 PS_TEXT    S_TEXT  VS_TEXT     D_TEXT  
 3          1       2           Oh
 6          2       2           Hi

所需的查询/ View 可以这样定义:

  • 每个不同的 S_TEXT 一行
  • 显示带有最新修订版 PS_TEXT 的 S_TEXT 的最新版本 VS_TEXT

最佳答案

在 MySQL 8.0 中,您可以为此使用 row_number():

create view vhs_text as
select ps_text, s_text, vs_text, d_text 
from (
    select 
        s.*,
        row_number() over(partition by s_text order by vs_text desc) rn
    from s_text s
) x
where rn = 1

Demo on DB Fiddle :

| ps_text | s_text | vs_text | d_text |
| ------- | ------ | ------- | ------ |
| 3       | 1      | 2       | Oh     |
| 6       | 2      | 2       | Hi     |

在早期版本中,您可以对相关子查询使用 NOT EXISTS 条件:

create view vhs_text as
select *
from s_text s
where not exists (
    select 1 
    from s_text s1
    where s1.s_text = s.s_text and s1.vs_text > s.vs_text
)

Demo on DB Fiddle (相同的结果)

关于php - 查看最新版本的删除历史记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58383206/

相关文章:

php - 如何在使用 MySQL 的子查询中执行 LEFT JOIN 两个表并从主查询中排除多行?

php - 我可以将 Ion auth 设置为通过用户名或电子邮件登录吗

php - 在 CakePHP 中将斜杠参数传递给 requestAction

php - 向 SuiteCRM 添加新模块

mysql - 创建一个 mySQL View ,其中每一行都是同一行中特定列的值

javascript - 将使用createElement(Javascript)创建的动态数据保存到数据库

php - CKeditor 表单将帖子添加到数据库时出现问题

php - 在 Laravel 中获取点 mysql 列

mysql - 在子查询中使用列,但不在主查询的 select 中使用列

mysql - 使用来自 1 个表的 1 列的变量的三个 MySQL 查询需要解析到临时表中