Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 根据号码的唯一ID更新号码_Sql Server - Fatal编程技术网

Sql server 根据号码的唯一ID更新号码

Sql server 根据号码的唯一ID更新号码,sql-server,Sql Server,我在SQL Server中有一个表,其中每个唯一的位置id都有一个唯一的SiteNumber。如果位置id不同,我尝试将每个SiteNumber递增1 例如: SITENUM LOCATION_ID 1234 8801 4567 8802 8910 8803 。。。等等 比方说,我现在已经为LOCATION_ID插入了新值,但我的SITENUM仍然为NULL NULL

我在SQL Server中有一个表,其中每个唯一的位置id都有一个唯一的SiteNumber。如果位置id不同,我尝试将每个SiteNumber递增1

例如:

SITENUM              LOCATION_ID
1234                 8801
4567                 8802
8910                 8803
。。。等等

比方说,我现在已经为LOCATION_ID插入了新值,但我的SITENUM仍然为NULL

NULL                 7000
NULL                 7001
NULL                 7002
1234                 8801
4567                 8802
等等

我的逻辑表明7000的sitenum应该是表中的MAXselect*sitenum 但是7001的下一个sitenum应该是表+1中的Maxselect*sitenum

现在,下面的代码一次将所有SiteNum更新为完全相同的值

UPDATE dbo.[Monthly Hierarchy Table]
SET SITENUM = MAX(SELECT SITENUM FROM [Monthly Hierarchy Table])+1
WHERE SITENUM IS NULL and location_id is not null
但我真的希望它能一行一行地运行,查看maxsitenum并基于非重复的location_id递增它。必须有某种方法可以将每个位置的id与自身进行比较,并在其为空且位置的id不同的地方增加sitenumber


我该怎么做呢?也许我的理解是不对的,但这是一个非常简单的问题。

问题是聚合函数max计算max值一次,然后将该值应用于与where子句匹配的所有记录。这是事务性/ACID兼容数据库的特性—在整个事务成功完成之前,对每个记录的单个更新对您来说都是不可见的


您可能需要编写一个小的存储过程,该过程使用一个游标循环遍历每个null sitenum记录;应该没那么难。

你可以这样做:

declare @num int;
set @num = (select max(LOCATION_ID) from MyTable);
update MyTable 
set SITENUM = @num, @num = @num + 1
where SITENUM is null and LOCATION_ID is not null
UPDATE dbo.[Monthly Hierarchy Table]
SET SITENUM = (SELECT MAX(SITENUM)+1 FROM [Monthly Hierarchy Table])
WHERE SITENUM IS NULL and location_id is not null
首先,MAX函数在错误的位置,因此它应该如下所示:

declare @num int;
set @num = (select max(LOCATION_ID) from MyTable);
update MyTable 
set SITENUM = @num, @num = @num + 1
where SITENUM is null and LOCATION_ID is not null
UPDATE dbo.[Monthly Hierarchy Table]
SET SITENUM = (SELECT MAX(SITENUM)+1 FROM [Monthly Hierarchy Table])
WHERE SITENUM IS NULL and location_id is not null
不幸的是,这仍然对您没有帮助,因为sql数据库通常在更新任何行之前为所有行计算新值。这意味着您要将它们全部更新为相同的值

因此,您需要在几个语句中执行此操作:

BEGIN TRANSACTION
    DECLARE @NewSiteNum int
    SELECT @NewSiteNum = MAX(SiteNum)+1 FROM [Monthly Hierarchy Table]

    UPDATE dbo.[Monthly Hierarchy Table]
    SET SITENUM = SELECT @NewSiteNum,
        @NewSiteNum = @NewSiteNum + 1
    WHERE SITENUM IS NULL and location_id is not null
COMMIT

请注意此处的事务:这非常重要,否则您的SiteNums可能不会唯一。

这里是一个查询,没有执行此任务的过程代码、递归或游标:

从您的问题中,我不确定表是否可以具有重复的LocationID,因此在我的解决方案中,具有相同LocationID的行会获得重复的SiteNum

drop table t
go
create table t (sitenum int, locid int)
go
insert into t(sitenum, locid) values (null, 7000)
insert into t(sitenum, locid) values (null, 7000)
insert into t(sitenum, locid) values (null, 7001)
insert into t(sitenum, locid) values (null, 7002)
insert into t(sitenum, locid) values (1234, 8801)
insert into t(sitenum, locid) values (4567, 8802)
go 

update t4 set sitenum = t3.new_sitenum from
t t4 inner join
(
    select t1.locid, COUNT(*) + (select MAX(sitenum) from t) as new_sitenum from
        (select locid from t where sitenum is null group by locid) as t1
        inner join
        (select locid from t where sitenum is null group by locid) as t2
        on t1.locid >= t2.locid
    group by t1.locid
) as t3
on t4.locid = t3.locid

select * from t
结果:

sitenum locId
4568    7000
4568    7000
4569    7001
4570    7002
1234    8801
4567    8802
关键是将表自连接到自身。连接条件为

t1.locId>=t2.locId


然后按t1.locId分组,并使用COUNT*聚合为每行提供一个从1开始有效计数的数字。最里面的GROUP BY用于处理重复的LOCID。最后,通过将locId连接到子查询进行更新。

以下代码也不起作用,返回一个语法错误,该错误位于=declare@i int;设置@i=0;虽然@i我的loc.id都是唯一的,但这个解决方案实际上要好得多,因为我可以引用我的loc.id并根据相同的值对它们进行分组。事实上,这对我的问题非常有效;