如何使用同一表中现有记录的值更新记录值

时间:2017-02-09 18:22:29

标签: sql sql-server sql-server-2012

使用SQL Server 2012:

我需要在这里做类似的事情,但我需要按如下方式更改值:

mytable中的每个M_id有2条记录,由MAS区分。凡价值为" 1"发生在MAS = 1记录的任何值(1-80)字段中,我需要更新记录MAS = 2中的值以匹配:

在:

id |  M_id | MAS | value1 | value2 | value3.....up to value80
---|-------|-----|--------|--------|-------|
 1 |  100  |  1  |   0    |    1   |   0
 2 |  100  |  2  |   0    |    0   |   0

在:

id |  M_id | MAS | value1 | value2 | value3.....up to value80
---|-------|-----|--------|--------|-------|
 1 |  100  |  1  |   0    |    1   |   0
 2 |  100  |  2  |   0    |    1   |   0

我需要对列表中包含M_id的3000多条记录执行此操作。

对于我来说,这有点复杂,任何人都知道如何做到这一点?

非常感谢,

MP

3 个答案:

答案 0 :(得分:1)

这应该这样做:

 update mytable_mas2
    set value1 = mytable_mas1.value1,
    value2 = mytable_mas1.value2,...

    from mytable mytable_mas2
            join mytable mytable_mas1
               on mytable_mas2.m_id = mytable_mas1.m_id
    where mytable_mas2.mas = 2
    and mytable_mas1.mas= 1
    and mytable_mas1.m_id in (200,201, ...)

如果您只想要特定的m_id受影响,请在(ids列表)中添加和m1.m_id。

答案 1 :(得分:0)

如果您有80列,则更容易使用动态SQL而不是编写整个Update查询。

DECLARE @strQuery Varchar(MAX)

SET @strQuery = 'UPDATE T1 SET '

SELECT @strQuery = @strQuery + 'T1.' + COLUMN_NAME + ' = T2.' + COLUMN_NAME + ' ,'
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'MyTable' AND COLUMN_NAME Like 'Value%'

SET @strQuery = SUBSTRING(@strQuery,1,LEN(@strQuery) - 1) + ' FROM MyTable T1 INNER JOIN MyTable T2
                ON T1.m_id = T2.m_id
                WHERE T1.mas = 2
                AND T2.mas= 1
                AND T1.m_id IN(100,200,300,400,500)   '

-- IN Clause added after on the OP demand

--If you want to show up your Query
SELECT(@strQuery)
-- To execute it
EXEC(@strQuery)

注意:我只会更新记录,其中m_id = 100或200或300或400或500

如果您在编写整个查询时没有问题,@ Mike的答案将适合您。

答案 2 :(得分:0)

您遇到了设计错误:"数组"列。现在您要搜索该数组,并找不到好的方法来执行此操作,因为您未按预期使用SQL。

编号列几乎总是将数据保存在元数据中的示例。如果我们将数据移回表中,SQL就变得容易了。

假设您有一个value列和一个ordinal列,可以说明它是哪一列:

create table T( id int, M_id int, MAS int, 
                ordinal int not NULL check (ordinal between 1 and 80), 
                value int );

update T
set value = (
    select value from T as T2
    where T.id = T2.id and T.M_id = T2.M_id and T.ordinal = T2.ordinal 
    and MAS = 1
    )
where MAS = 2
and exists (
    select 1 from T as T2
    where T.id = T2.id and T.M_id = T2.M_id and T.ordinal = T2.ordinal 
    and MAS = 1
)

这是一个单一的更新声明。它使用ANSI标准语法来避免专有T-SQL update from构造可能导致的异常。

除了其他优点之外,您不再需要存储零。您可以将缺失值(不存在的行)视为隐含的零。这会使你的更新变得更复杂;谢天谢地,SQL Server支持merge

如果您想以您设计的方式查看您的桌子,那么您将不会成为第一个。写一个视图来呈现它;它通常被称为 table-folding