MySQL更新列的序列号按具有相同值的字段分组

Posted

技术标签:

【中文标题】MySQL更新列的序列号按具有相同值的字段分组【英文标题】:MySQL update column with sequential numbers grouped by a field with the same value 【发布时间】:2019-05-01 05:44:07 【问题描述】:

我想使用具有相同值的字段作为参考,在我的 mysql 表的列中进行大规模更新。 更新是分组时重复的数字序列。

MySQL 版本:

5.6.41-84.1

MySQL 表:

sis_coautoria

列和值

id_auto_coautoria | id_coautor | hierarquia_coautoria | id_trabalho

1, 1, null, 123
2, 43, null, 123
3, 2, null, 123
4, 2, null, 100
5, 1, null, 675
6, 50, null, 100

我想更新 hierarquia_coautoria 列,使用 id_trabalho 列作为参考,id_auto_coautoria 作为 ORDER BY。预期的结果是这样的:

id_auto_coautoria | id_coautor | hierarquia_coautoria | id_trabalho

1, 1, 1, 123
2, 43, 2, 123
3, 2, 3, 123
4, 2, 1, 100
6, 50, 2, 100
5, 1, 1, 675

id_trabalho = 123 的行更新为 1, 2, 3; id_trabalho = 100 更新为 1, 2 等等。


*如果需要,还有另一个带有 id_trabalho 列 的表作为参考。

其他 MySQL 表

sis_trabalhos

id_auto_trabalho | id_trabalho

1, 123
2, 100
3, 675

所以,我尝试了这样的方法:

SET @rank:=0;
UPDATE sis_coautoria
INNER JOIN sis_trabalhos ON sis_coautoria.id_trabalho = sis_trabalhos.id_trabalho
SET sis_coautoria.hierarquia_coautoria=@rank:=@rank+1; 

结果:

id_auto_coautoria | id_coautor | hierarquia_coautoria | id_trabalho

1, 1, 1, 123
2, 43, 2, 123
3, 2, 3, 123
4, 2, 4, 100
5, 1, 5, 675
6, 50, 6, 100
...

结果是一个忽略 id_trabalho 条件为相同值的数字序列。


PS.: 我怎样才能以这样的友好视图显示 MySQL 表

【问题讨论】:

【参考方案1】:

我的理解是,您需要一组 id_trabalho 列的行号。由于 Mysql 5 没有 CTE,您可以使用子查询来执行相同的操作。

    update sis_coautoria a
join 
(SELECT 
    @row_number:=CASE
        WHEN @id_trabalho = id_trabalho THEN @row_number + 1
        ELSE 1
    END AS rn,
    @id_trabalho:=id_trabalho as id_trabalho,
    id_auto_coautoria
FROM
    sis_coautoria
ORDER BY id_auto_coautoria)
cte on a.id_auto_coautoria=cte.id_auto_coautoria
set a.hierarquia_coautoria=cte.rn

注意:我没有在编辑器上运行此查询。

【讨论】:

注意:MySQL-5.6 没有 CTE,它是 MySQL-8.0+ 的一个特性。 是的!我遇到了这个错误:您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以获取在 'cte 附近使用的正确语法,因为我将搜索相关的内容。 @BlackSwan 我收到此错误:您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 3 行的 '(partition by id_trabalho order by id_auto_coautoria asc) rn from sis_coautoria) c' 附近使用正确的语法 在 MySQL 5 中好像不支持窗口函数。让我检查一下 MySQL 中是否有等效于窗口函数的功能 @BlackSwan hierarquia_coautoria 列每行更新为“1”。没有顺序。【参考方案2】:

重要 此答案适用于 MySQL 5MySQL 8(或更新版本)有其他方法可以获得相同的结果。

@BlackSwan 的贡献帮助我得到了我的问题的答案。谢谢!

我的 MySQL 服务器版本是 5.6,不允许使用 number_row() 函数或 CTE 程序。因此,解决方案是使用子查询模拟 MySQL ROW_NUMBER() 函数来填充新列“sequencia”,该列用于更新我想要的列 (hierarquia_coautoria)。 p>

获取期望结果的代码如下:

update sis_coautoria a
join 
(SELECT 
    @row_number:=CASE
        WHEN @trabalhoID = id_trabalho THEN @row_number + 1
        ELSE 1
    END AS sequencia,
    @trabalhoID:=id_trabalho as trabalho_id,
    id_coautor_auto,
    id_usuario
FROM
    sis_coautoria,(SELECT @trabalhoID:=0,@row_number:=0) as t
ORDER BY id_trabalho ASC)
cte on a.id_coautor_auto=cte.id_coautor_auto
set a.hierarquia_coautoria=cte.sequencia

代码说明:

我们使用一个变量(@row_number)来存储行的计数,满足以下条件:当trabalho_id具有相同的值时,将在中以数字顺序的方式添加一个新的行号sequencia 列。

@row_number:=CASE
            WHEN @trabalhoID = id_trabalho THEN @row_number + 1
            ELSE 1
        END AS sequencia

按顺序,我们使用条件连接引用的列,并使用存储在 sequencia 列中的值更新所需的列 (hierarquia_coautoria)。

cte on a.id_coautor_auto=cte.id_coautor_auto
    set a.hierarquia_coautoria=cte.sequencia 

其他信息:

链接到row_number() emulation tutorial

链接到ROW_NUMBER() function in MySQL 8

About CTE (MySQL 8+)

【讨论】:

。 .这些答案不正确,因为您正在分配一个变量并在SELECT 中的不同表达式中使用它。 MySQL 明确不保证 SELECT 中表达式的求值顺序,因此即使此代码现在似乎可以处理您的特定数据,也不能保证它可以工作。 你是对的,但答案表明了解决问题的途径。我们指出了如何通过 MySQL 函数和过程获得可能的解决方案。

以上是关于MySQL更新列的序列号按具有相同值的字段分组的主要内容,如果未能解决你的问题,请参考以下文章

【SQL】根据一个字段分组求另一个字段的最大值,并带出其他字段

mysql 按字段a排序 并编序列号,字段a值相同的编号相同

mysql group by 对多个字段进行分组

mysql group by 详解

根据另一列的字段值选择具有相同列值的行

如何将所有字段都是默认值的类型反序列化为 None ?