2017-08-28 82 views
1

我有要求用不同的密钥更新两行的列值。约束是我想在单个查询中做到这一点。在单个SQL查询中交换同一表的列值

例如:

Coll1 Coll2 
--------------- 
    A  1 
    B  2 
    C  3 

应该像使用case表达

Coll1 Coll2 
-------------- 
    A  3 
    B  2 
    C  1 
+0

SqlZim是对的,但你为什么要在单个查询中做到这一点? –

+1

更合适的词将是'单笔交易'。 – ggtffg

+0

我刚刚添加了一个通用的解决方案,没有硬编码任何值 – Horaciux

回答

6

update t 
    set Coll2 = case when Coll1 = 'A' then 3 else 1 end 
where Coll1 in ('A','C') 

rextester演示:http://rextester.com/HUBDAP9516

返回:

+-------+-------+ 
| Coll1 | Coll2 | 
+-------+-------+ 
| A  |  3 | 
| B  |  2 | 
| C  |  1 | 
+-------+-------+ 

更新参数化版本:

declare @key1 char(1) = 'A'; 
declare @key2 char(1) = 'C'; 
update t 
    set t.Coll2 = x.Coll2 
from t 
    inner join t x 
    on t.Coll1 <> x.Coll1 
    and t.Coll1 in (@key1,@key2) 
    and x.Coll1 in (@key1,@key2) 

rextester演示:http://rextester.com/PKQSAV63963

回报:

+-------+-------+ 
| Coll1 | Coll2 | 
+-------+-------+ 
| A  |  3 | 
| B  |  2 | 
| C  |  1 | 
+-------+-------+ 
+2

当它,打我吧哈哈 – scsimon

+2

啊,甚至演示! :P – xQbert

+0

你可以看看我提出的解决方案吗? – Horaciux

3

也许你的意思是一个单一的交易。无论哪种方式,我都不明白为什么 - 但既然这就是你想要的,这是一个简单的方法。

declare @table table (Col1 char(1), Col2 int) 
insert into @table 
values 
('A',1), 
('B',2), 
('C',3) 

update @table 
set 
    Col2 = case 
       when Col1 = 'A' then 3 
       when Col1 = 'C' then 1 
      end 
where Col1 in ('A','C') 

select * from @table 
+1

where子句可以节省大量工作。 – xQbert

+0

这很公平@xQbert:D – scsimon

+2

C陛下。不是B. xQbert

1
BEGIN TRANSACTION 
UPDATE t SET Coll2 = 3 WHERE Coll1 = 'A' 
UPDATE t SET Coll2 = 1 WHERE Coll1 = 'C' 
COMMIT 
0

我想试试下面的答案,而不硬编码COL2

create table #t (col1 char(301), col2 int); 
go 
insert into #t (col1, col2) 
values ('A', 1), ('B', 2), ('C', 3) 

; with c as (
select col1, col2 
from #t 
) 
update t 
set t.col2 = c.col2 
from #t t 
inner join c 
on abs(ascii(t.col1) - ascii(c.col1))=2 


select * from #t 
+0

你会看看我提出的解决方案吗? – Horaciux

0

这是你有价值观切换的参数或子查询的通用解决方案。

它也适用于con char数据,但需要对字符串操作进行一些调整。

declare @table table (Col1 char(1), Col2 int) 
insert into @table 
values 
('A',1), 
('B',2), 
('C',3) 


declare @swap1 char='A' 
declare @swap2 char='C' 

update @table 
set col2 = (select sum(col2) from @table 
    where col1 in (@swap1,@swap2))-col2 
where col1 in (@swap1,@swap2) 
+1

尽管您参数化了查询,但最好在我的和SQLZim的解决方案中对case语句进行参数化。然后,它会处理非数字数据。另外,您已经引入了必要的聚合。这是一种不同而且聪明的方法,但性能较差。抽象思维虽然 - 做得好 – scsimon

+0

@scsimon谢谢。国际海事组织的问题不是硬编码搜索文本,而是两个答案中的值。你们是否可以按照OP的要求在一句话中做到这一点? – Horaciux

+0

@Horaciux,你的解决方案是一个非常好的问题与它的数据,因为它的数据(即col2是int)。 – jyao

相关问题