基于行和列位置的 SQL UPDATE 值,没有 ID 或键
Posted
技术标签:
【中文标题】基于行和列位置的 SQL UPDATE 值,没有 ID 或键【英文标题】:SQL UPDATE value based on row and column location without ID or key 【发布时间】:2021-02-26 20:59:46 【问题描述】:在 SQL 中(我使用的是 postgres,但对其他变体持开放态度),当表没有唯一的行或键时,是否可以根据行位置和列名更新值? ...不添加包含唯一值的列?
以表格为例:
col1 | col2 | col3 |
---|---|---|
1 | 1 | 1 |
1 | 1 | 1 |
1 | 1 | 1 |
我想根据行号或行号更新表格。例如,将第 1 行和第 3 行的值将 col2 更改为 5,如下所示:
col1 | col2 | col3 |
---|---|---|
1 | 5 | 1 |
1 | 1 | 1 |
1 | 5 | 1 |
我可以从示例表开始:
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 * FROM (
SELECT *, ROW_NUMBER() OVER() FROM test_table
) as sub
WHERE row_number BETWEEN 1 AND 2
但这似乎不适用于更新功能(至少在 postgres 中)。同样,我尝试过使用一些子集或公用表表达式,但我再次遇到了 UPDATE 方面的困难。我怎样才能执行完成类似这样的伪代码的事情?:UPDATE <my table> SET <col name> = <new value> WHERE row_number = 1 or 3, or...
这是微不足道的其他语言,如 R 或 python(例如,使用 pandas 的 .iloc 函数)。知道如何在 SQL 中执行此操作会很有趣。
编辑:在我的表格示例中,我应该将列类型指定为 int。
【问题讨论】:
“我可以使用类似的东西根据行号进行选择:...”。这不是确定性的。这个row_number
与任何“插入订单”或其他无关。您的查询每次都可能返回不同的结果。见***.com/questions/18613055/…
SQL 表根据关系的定义是无序的(当然,它们有一些 DBMS 用来访问每一行的内部排序),因此表中没有没有明确顺序的第 N 行。您的电子表格数据是明确排序的,因为您可以从上到下找到行的序数位置,尽管其中没有任何书面数字。您可以使用 row_number() over(order by ...)
之类的一些函数指定显式行索引,但它必须有一些 order by
订购的要点(或缺少要点)。如果我真的想进行脑力锻炼,我可能会使用 DBMS 的伪 id(例如 postgres 中的 ctid)。
【参考方案1】:
这是您应该拥抱较小的邪恶即代理键的众多实例之一。无论哪个表的主键为 (col1,col2,col3),都应该有一个由系统创建的附加键,例如身份或 GUID。
您没有指定 (col1,col2,col3) 的数据类型,但是如果由于某种原因您对代理键过敏,您可以接受“组合键”的稍大的弊端,而不是数据库创建的值您的唯一键字段是从其他一些字段派生的。 (在这种情况下,它类似于 CONCAT(col1, '-', col2, '-', col3) )。
如果上述两种方法都不实用,您将面临每次查询记录时必须手动指定所有三列的最大弊端。这意味着任何其他引用此对象或表的对象或表都需要具有三个不同的字段来识别您正在谈论的记录。
理想情况下,顺便说一句,您可以在实际数据中拥有一些业务密钥,您可以通过设计保证这些密钥是唯一的、永不更改的、永不空白的。 (或者至少更改如此不频繁以至于数据库可以很好地处理级联更新。)
在这种情况下,您最终可能会使用代理键来提高性能,但这是实现细节,而不是数据建模要求。
【讨论】:
以上是关于基于行和列位置的 SQL UPDATE 值,没有 ID 或键的主要内容,如果未能解决你的问题,请参考以下文章