根据多行更新列值
Update column value based on the multiple rows
我有一个 table 示例:(Col3 是位数据类型)
col1 | col2 | col3
____________________
abc | xyz | 0
abc | xyz | 1
abc | xyz | 0
abc | xyz | 0
我想 select 与 table 不同,col3 除外,如果 col3 值不同,则将 col3 值更新为 0。 (如果所有 col3 值都相同,则不同的将 return 不同的行)。
这里我期望输出为:
col1 | col2 | col3
____________________
abc | xyz | 0
有什么帮助吗?
编辑
当 col3 值相同时:
col1 | col2 | col3
____________________
abc | xyz | 0
abc | xyz | 0
abc | xyz | 0
abc | xyz | 0
col1 | col2 | col3
____________________
abc | xyz | 1
abc | xyz | 1
abc | xyz | 1
abc | xyz | 1
编辑
此外,如果我只想更新其中的几行,那该怎么做呢?示例:
如果存在数据:
col1 | col2 | col3
____________________
abc | xyz | 0
abc | xyz | 1
abc | xyz | 1
abc | xyz | 0
qwe | asd | 1
qwe | asd | 0
qwe | asd | 0
qwe | asd | 0
预期输出:
col1 | col2 | col3
____________________
abc | xyz | 0
qwe | asd | 0
这是你想要的吗?
select distinct col1, col2, 0 as col3
from t;
或者也许:
select col1, col2, 0 as col3
from t
group by col1, col2
having min(col3) <> max(col3)
union all
select col1, col2, col3
from t
where not exists (select 1
from t
where t2.col1 = t.col1 and t2.col2 = t.col2 and
t2.col3 <> t.col3
);
这也可以用window函数表示:
select col1, col2,
(case when min_col3 = max_col3 then max(col3) else 0 end) as col3
from (select t.*,
row_number() over (partition by col1, col2 order by col3) as seqnum,
max(col3) over (partition by col1, col2) as max_col3,
min(col3) over (partition by col1, col2) as min_col3
from t
) t
group by col1, col2, min_col3, max_col3,
(case when min_col3 = max_col3 then seqnum else 0 end)
您可以 group by col1, col2
和 case
表达式 col3
:
select col1, col2,
case when min(cast(col3 as int)) = max(cast(col3 as int)) then 1 else 0 end col3
from tablename
group by col1, col2
参见demo。
结果:
> col1 | col2 | col3
> :--- | :--- | ---:
> abc | xyz | 0
您可以使用 row_number()
函数、cte
和 inner join
尝试以下查询,如下所示。
注意:如果您想用重复的值更新值并保留这些条目中的值,在这种情况下您不需要再次加入 table。
create table SampleTable( col1 varchar(10)
, col2 varchar(10)
, col3 bit)
insert into SampleTable values
('abc', 'xyz', 0),
('abc', 'xyz', 1),
('abc', 'xyz', 0),
('abc', 'xyz', 0)
--Before update
select * from SampleTable
--Getting rows with duplicate
; with cte as (SELECT col1
, col2
, col3
, row_number() over (partition by col1, col2, col3 order by (select null)) as cnt
FROM SampleTable
)UPDATE t
set t.col1 = t.col1
, t.col2 = t.col2
, t.col3 = 1
from SampleTable t
inner join cte on t.col1 = cte.col1
and t.col2 = cte.col2 and t.col3 = cte.col3
and cnt > 1
--After update
select * from SampleTable
这是现场 db<>fiddle 演示。
这是另一种使用 exists
的方法。
第二种方法
update t1
set t1.col1 = t1.col1
, t1.col2 = t1.col2
, t1.col3 = 1
from SampleTable t1
where exists (select 1
from SampleTable t2
where t1.col1 = t2.col1
and t1.col2 = t2.col2
and t1.col3 = t2.col3
group by col1, col2, col3
having count(*) > 1)
您可以使用 EXISTS
:
UPDATE t
SET t.col3 = (CASE WHEN EXISTS (SELECT 1
FROM table t1
WHERE t1.col1 = t.col1 AND
t1.col2 = t.col2 AND
t1.col3 <> t.col3
)
THEN 0 ELSE 1
END)
FROM table t;
对于您的具体示例,您可以按 (col1,col2) 分组,然后取 min(col3)
我有一个 table 示例:(Col3 是位数据类型)
col1 | col2 | col3
____________________
abc | xyz | 0
abc | xyz | 1
abc | xyz | 0
abc | xyz | 0
我想 select 与 table 不同,col3 除外,如果 col3 值不同,则将 col3 值更新为 0。 (如果所有 col3 值都相同,则不同的将 return 不同的行)。
这里我期望输出为:
col1 | col2 | col3
____________________
abc | xyz | 0
有什么帮助吗?
编辑
当 col3 值相同时:
col1 | col2 | col3
____________________
abc | xyz | 0
abc | xyz | 0
abc | xyz | 0
abc | xyz | 0
col1 | col2 | col3
____________________
abc | xyz | 1
abc | xyz | 1
abc | xyz | 1
abc | xyz | 1
编辑
此外,如果我只想更新其中的几行,那该怎么做呢?示例:
如果存在数据:
col1 | col2 | col3
____________________
abc | xyz | 0
abc | xyz | 1
abc | xyz | 1
abc | xyz | 0
qwe | asd | 1
qwe | asd | 0
qwe | asd | 0
qwe | asd | 0
预期输出:
col1 | col2 | col3
____________________
abc | xyz | 0
qwe | asd | 0
这是你想要的吗?
select distinct col1, col2, 0 as col3
from t;
或者也许:
select col1, col2, 0 as col3
from t
group by col1, col2
having min(col3) <> max(col3)
union all
select col1, col2, col3
from t
where not exists (select 1
from t
where t2.col1 = t.col1 and t2.col2 = t.col2 and
t2.col3 <> t.col3
);
这也可以用window函数表示:
select col1, col2,
(case when min_col3 = max_col3 then max(col3) else 0 end) as col3
from (select t.*,
row_number() over (partition by col1, col2 order by col3) as seqnum,
max(col3) over (partition by col1, col2) as max_col3,
min(col3) over (partition by col1, col2) as min_col3
from t
) t
group by col1, col2, min_col3, max_col3,
(case when min_col3 = max_col3 then seqnum else 0 end)
您可以 group by col1, col2
和 case
表达式 col3
:
select col1, col2,
case when min(cast(col3 as int)) = max(cast(col3 as int)) then 1 else 0 end col3
from tablename
group by col1, col2
参见demo。
结果:
> col1 | col2 | col3
> :--- | :--- | ---:
> abc | xyz | 0
您可以使用 row_number()
函数、cte
和 inner join
尝试以下查询,如下所示。
注意:如果您想用重复的值更新值并保留这些条目中的值,在这种情况下您不需要再次加入 table。
create table SampleTable( col1 varchar(10)
, col2 varchar(10)
, col3 bit)
insert into SampleTable values
('abc', 'xyz', 0),
('abc', 'xyz', 1),
('abc', 'xyz', 0),
('abc', 'xyz', 0)
--Before update
select * from SampleTable
--Getting rows with duplicate
; with cte as (SELECT col1
, col2
, col3
, row_number() over (partition by col1, col2, col3 order by (select null)) as cnt
FROM SampleTable
)UPDATE t
set t.col1 = t.col1
, t.col2 = t.col2
, t.col3 = 1
from SampleTable t
inner join cte on t.col1 = cte.col1
and t.col2 = cte.col2 and t.col3 = cte.col3
and cnt > 1
--After update
select * from SampleTable
这是现场 db<>fiddle 演示。
这是另一种使用 exists
的方法。
第二种方法
update t1
set t1.col1 = t1.col1
, t1.col2 = t1.col2
, t1.col3 = 1
from SampleTable t1
where exists (select 1
from SampleTable t2
where t1.col1 = t2.col1
and t1.col2 = t2.col2
and t1.col3 = t2.col3
group by col1, col2, col3
having count(*) > 1)
您可以使用 EXISTS
:
UPDATE t
SET t.col3 = (CASE WHEN EXISTS (SELECT 1
FROM table t1
WHERE t1.col1 = t.col1 AND
t1.col2 = t.col2 AND
t1.col3 <> t.col3
)
THEN 0 ELSE 1
END)
FROM table t;
对于您的具体示例,您可以按 (col1,col2) 分组,然后取 min(col3)