Sql 更新表中的行
我有一张桌子,下面有一列Sql 更新表中的行,sql,oracle,Sql,Oracle,我有一张桌子,下面有一列 Fruit_Name(varchar2(10)) | IsDuplicate Number(1) Mango 0 Orange 0 Mango 0 我要做的是将IsDuplicate列更新为1,其中水果名称不同,即 Fruit_Name(varchar2(10)) | IsDuplic
Fruit_Name(varchar2(10)) | IsDuplicate Number(1)
Mango 0
Orange 0
Mango 0
我要做的是将IsDuplicate列更新为1,其中水果名称不同,即
Fruit_Name(varchar2(10)) | IsDuplicate Number(1)
Mango 1
Orange 1
Mango 0
我该怎么做呢?直截了当的简单——你不能。不是普通SQL。SQL是一种基于集合的处理语言,您可以在集合中进行操作。SQL无法知道您的许多芒果中的哪一个应该标记为1。您可能可以在SELECT中使用窗口功能或ROWNUM等将其中一个标记为1,但我认为这不能通过更新来完成 换句话说,您的表首先缺少一个唯一的键,因此SQL并不是专门为处理这个键而设计的 但是,您可以尝试向每一行添加顺序主键。然后,您可以轻松编写一个更新查询,将COUNT>1且key=MINkey的所有行设置为1
换句话说,您真的必须查看您的数据库设计。关系数据库不应该包含重复项。您需要将某些内容标记为副本这一事实意味着您的表首先设计错误。数据库甚至不应该允许重复输入数据。简单明了-你不能。不是普通SQL。SQL是一种基于集合的处理语言,您可以在集合中进行操作。SQL无法知道您的许多芒果中的哪一个应该标记为1。您可能可以在SELECT中使用窗口功能或ROWNUM等将其中一个标记为1,但我认为这不能通过更新来完成 换句话说,您的表首先缺少一个唯一的键,因此SQL并不是专门为处理这个键而设计的 但是,您可以尝试向每一行添加顺序主键。然后,您可以轻松编写一个更新查询,将COUNT>1且key=MINkey的所有行设置为1
换句话说,您真的必须查看您的数据库设计。关系数据库不应该包含重复项。您需要将某些内容标记为副本这一事实意味着您的表首先设计错误。数据库甚至不应该允许重复输入数据。据我所知,这应该可以做到
update fruits
set is_duplicate =
(
select case
when dupe_count > 1 and row_num = 1 then 1
else 0
end as is_dupe
from (
select f2.fruit_name,
count(*) over (partition by f2.fruit_name) as dupe_count,
row_number() over (partition by f2.fruit_name order by f2.fruit_name) as row_num,
rowid as row_id
from fruits f2
) ft
where ft.row_id = fruits.rowid
and ft.fruit_name = fruits.fruit_name
)
编辑
但是,与其实际更新表,不如创建一个返回信息的视图。根据表的大小,它可能更有效
create view fruit_dupe_view
as
select fruit_name,
case
when dupe_count > 1 and row_num = 1 then 1
else 0
end as is_duplicate
from (
select fruit_name,
count(*) over (partition by fruit_name) as dupe_count,
row_number() over (partition by fruit_name order by fruit_name) as row_num
from fruits
) ft
据我所知,这应该可以做到
update fruits
set is_duplicate =
(
select case
when dupe_count > 1 and row_num = 1 then 1
else 0
end as is_dupe
from (
select f2.fruit_name,
count(*) over (partition by f2.fruit_name) as dupe_count,
row_number() over (partition by f2.fruit_name order by f2.fruit_name) as row_num,
rowid as row_id
from fruits f2
) ft
where ft.row_id = fruits.rowid
and ft.fruit_name = fruits.fruit_name
)
编辑
但是,与其实际更新表,不如创建一个返回信息的视图。根据表的大小,它可能更有效
create view fruit_dupe_view
as
select fruit_name,
case
when dupe_count > 1 and row_num = 1 then 1
else 0
end as is_duplicate
from (
select fruit_name,
count(*) over (partition by fruit_name) as dupe_count,
row_number() over (partition by fruit_name order by fruit_name) as row_num
from fruits
) ft
实际上,这个表是oracle的一个外部表,不管是内部表还是外部表。您无法在使用SQL的更新中区分重复项-这不是SQL设计的目的。与数据库无关-您可以在其中输入任何您想要的内容。你不能用一种设计为基于集合的语言来操作它。实际上,这个表是oracle的一个外部表。它是内部表还是外部表都没有关系。您无法在使用SQL的更新中区分重复项-这不是SQL设计的目的。与数据库无关-您可以在其中输入任何您想要的内容。你就是不能用一种设计成基于集合的语言来操纵它。@horse有一个rowid在里面,而他的表中没有id,您的rowid来自何处?这个查询对我来说有点高,如果我很愚蠢的话,很抱歉。@EmreVeryaz:这是Oracle的一个内部列,唯一地标识每一行。如果这真的有效,我将得到纠正。但是,要修复一个糟糕的表设计,需要经历一场混乱。@Brian:我同意,信息总是可以很容易地检索到。@Brian:是的,这是可能的。尤其是在一个单独的语句中。您不能依赖上一条语句或事务中的rowid仍然引用同一行的事实。@a_horse_没有名字,您在其中有一个rowid,而他的表中没有id,您的rowid来自何处?这个查询对我来说有点高,如果我很愚蠢的话,很抱歉。@EmreVeryaz:这是Oracle的一个内部列,唯一地标识每一行。如果这真的有效,我将得到纠正。但是,要修复一个糟糕的表设计,需要经历一场混乱。@Brian:我同意,信息总是可以很容易地检索到。@Brian:是的,这是可能的。尤其是在一个单独的语句中。您不能依赖上一个语句或事务中的rowid仍然引用同一行这一事实。从技术上讲,这不是问题,但是。。。为什么实际副本的IsDuplicate应为0,否则为1?也就是说,该列的名称可能应该有所不同,可能是“IsFirstOccurrence”或类似的名称。从技术上讲,这不是问题,但。。。为什么实际副本的IsDuplicate应为0,否则为1?也就是说,列的名称可能应该不同,可能是'IsFirstOccurrence'或其他类似的名称 g.排队。