从自身表更新表中的值不为空的表

时间:2019-01-15 06:49:29

标签: sql sql-server tsql sql-update

我有一个包含值的表:

dbid    name         userid
------------------------------
154     xyz          NULL
987     xyz          NULL
777     xyz          5
111     abc          NULL
745     abc          NULL
748     abc          6

预期输出:

dbid     name     userid
------------------------------
154     xyz          5
987     xyz          5
777     xyz          5
111     abc          6
745     abc          6
748     abc          6

除了一个一对一的名称,userid列中所有空值。我想在name ='xyz'的所有行的用户ID中设置5。 同样,要更新表以将userid设置为6,其中name ='abc'。

针对上述情况更新表的查询应该是什么?

注意:以上仅是示例。我有一个包含数十万条记录的表。我无法在查询中输入ID 5或6。

8 个答案:

答案 0 :(得分:3)

尝试

update table_name 
   set table_name.userid = (
        select top(1) ss.userid 
          from table_name ss 
         where ss.name = table_name.name 
           and ss.userid is not null
        ) 
    where table_name.userid is null

此查询正在搜索名称相同的第一条记录userid并在userid为空的情况下进行更新

答案 1 :(得分:2)

考虑到name代表userid的事实,您可以使用单个UPDATE语句更新表。您可以使用以下查询,但前提是仅存在那些对属性的独特依赖。

UPDATE table_name
SET name = (SELECT TOP 1 temp.userid FROM table_name temp WHERE temp.name = name)
WHERE userid is null;

答案 2 :(得分:1)

我是否应该假定表防御中的列dbid和名称不为null?那么,问题是否也是“输出”,是否要作为查询,视图或SP的结果?总之,我会亲自将桌子分成两张桌子。

表1:

dbid     name  
---------------
154     xyz    
987     xyz    
777     xyz    
111     abc    
745     abc    
748     abc

表2:

name     userid
------------------
xyz      5
abc      6

然后,当我想要特定的dbid的用户ID时,我会简单地:

SELECT A.dbid, A.name, B.userid FROM DATABASE.TABLE1 A INNER JOIN DATABASSE.TABLE2 B ON A.name = B.name

这将导致输出表:

dbid     name     userid
------------------------------
154     xyz          5
987     xyz          5
777     xyz          5
111     abc          6
745     abc          6
748     abc          6

答案 3 :(得分:1)

尝试一下:

DECLARE @DataSource TABLE
(
    [dbid] INT
   ,[name] SYSNAME
   ,[userid] SMALLINT
);

INSERT INTO @DataSource ([dbid], [name], [userid])
VALUES (154, 'xyz', NULL)
      ,(987, 'xyz', NULL)
      ,(777, 'xyz', 5)
      ,(111, 'abc', NULL)
      ,(745, 'abc', NULL)
      ,(748, 'abc', 6);

WITH DataSource AS
(
    SELECT [dbid]
          ,[name]
          ,[userid]
          ,MIN([userID]) OVER (PARTITION BY [name]) AS [userid_precalc]
    FROM @DataSource
)
UPDATE DataSource
SET [userid] = [userid_precalc]
WHERE [userid] IS NULL;

SELECT *
FROM @DataSource;

答案 4 :(得分:1)

请尝试以下查询

update table_name
set userid=(select top 1 T.userid from table_name T where T.name=table_name.name and T.userid is not null )
where userid is null

答案 5 :(得分:1)

尝试一下:

1)将数据选择到虚拟表中。

SELECT * INTO dummy_tbl FROM myTable WHERE userid is not null

查询应插入UserID不为null的所有数据。

2)执行更新命令

update myTable set userid = (select userID from dummy_tbl where dummy_tbl.name  = myTable.name)

3)删除创建的虚拟表。

drop table dummy_tbl

一切顺利,所有用户ID均已相应更新。

BR,莫伊德

答案 6 :(得分:0)

使用两个更新查询

pri_queue.execute_all()

答案 7 :(得分:0)

由于您有大量记录要更新表变量,因此应避免使用窗口函数。

我的想法类似于@Moiyd。

首先在原始表名列上创建非聚集索引。如果用户尚未聚集索引,则

Create Non Clustered index ix_myTable_name on myTable(name) include(userid)

如果userid是CI,则不需要

include(userid)

在单独的表中存储非空名称和用户ID。

Create table dummy_tbl (name varchar(100),userid int)

Create Non Clustered index ix_dummy_name on dummy_tbl(name) include(userid)

insert into dummy_tbl (userid,name)
SELECT userid  FROM myTable WHERE userid is not null

update T 
set userid = T.userid
from myTable T
inner join dummy_tbl d on d.name  = T.name

Drop table dummy_tbl .

如果可能的话,请永久存储dummy_tbl的值,因为这是最好的normalise方法。您可以将所有non repeating列存储在dummy_tbl