SQL 根据没有 ID 或键的行和列位置更新值

SQL UPDATE value based on row and column location without ID or key

在 SQL 中(我使用的是 postgres,但对其他变体持开放态度),当 table 没有时,是否可以根据行位置和列名更新值有唯一的行或键? ...不添加包含唯一值的列?

例如,考虑 table:

col1 col2 col3
1 1 1
1 1 1
1 1 1

我想根据行号更新 table。例如,将第 1 行和第 3 行的值 col2 更改为 5,如下所示:

col1 col2 col3
1 5 1
1 1 1
1 5 1

我可以从例子开始 table:

CREATE TABLE test_table (col1 int, col2 int, col3 int);
INSERT INTO test_table (col1, col2, col3) values(1,1,1);
INSERT INTO test_table (col1, col2, col3) values(1,1,1);
INSERT INTO test_table (col1, col2, col3) values(1,1,1);

现在,我可以添加一个额外的列,说“id”并简单地:

UPDATE test_table SET col2 = 5 WHERE id = 1
UPDATE test_table SET col2 = 5 WHERE id = 3 

但这是否可以仅根据行号来完成?

我可以 select 基于行号使用类似的东西:

SELECT * FROM (
                SELECT *, ROW_NUMBER() OVER() FROM test_table 
                ) as sub
WHERE row_number BETWEEN 1 AND 2

但这似乎不能很好地配合更新功能(至少在 postgres 中)。同样,我曾尝试使用一些子集或常见的 table 表达式,但我再次 运行 遇到了 UPDATE 方面的困难。我怎样才能执行像这个伪代码这样的事情?:UPDATE <my table> SET <col name> = <new value> WHERE row_number = 1 or 3, or... 这对于像 R 或 python 这样的其他语言来说是微不足道的(例如,使用 pandas 的 .iloc 函数)。知道如何在 SQL.

中执行此操作会很有趣

编辑:在我的 table 示例中,我应该将列类型指定为类似 int 的类型。

这是您应该拥抱较小的邪恶(代理键)的众多实例之一。 table 具有 (col1,col2,col3) 主键的任何一个都应该具有系统创建的附加键,例如身份或 GUID。

您没有指定 (col1,col2,col3) 的数据类型,但如果由于某种原因您对代理键过敏,您可以接受“组合键”的稍微更大的邪恶,而不是数据库创建的值的唯一键字段来自其他一些字段。 (在这种情况下,它类似于 CONCAT(col1, '-', col2, '-', col3) )。

如果以上都不可行,您将面临最大的麻烦,即每次查询记录时都必须手动指定所有三列。这意味着引用此对象的任何其他对象或 table 需要的不是一个而是三个不同的字段来标识您正在谈论的记录。

理想情况下,顺便说一句,您可以在实际数据中拥有一些业务密钥,您可以通过设计保证这些密钥是唯一的、永不改变的、永不空白的。 (或者至少更改得如此之少,以至于数据库可以很好地处理级联更新。)

在这种情况下,您可能最终会使用代理键来提高性能,但这是一个实现细节,而不是数据建模要求。