如何在循环匹配条件下更新Sql Server表的记录?

问题描述 投票:0回答:2

我担心如果更新查询出错,它将影响整个表。

我在这里写的查询显示我有什么数据以及我将如何更新它,

SELECT BuildingId,VisitNumber,Id,TasksId,Status,GregorianDate
FROM Visit where status=5 and BuildingId in (7,8,9,10)
Group by BuildingId,Id,TasksId,Status,VisitNumber,GregorianDate
order by BuildingId,GregorianDate asc

BuildingId  VisitNumber Id  TasksId Status  GregorianDate
7            Visit_U_1  169     79    5     2018-04-09
7            Visit_U_1  1217    506   5     2018-08-01
7            Visit_U_1  2162    775   5     2019-01-09
8            Visit_U_1  148     72    5     2018-04-10
8            Visit_U_1  2206    783   5     2019-01-08
9            Visit_U_1  161     76    5     2018-04-10
9            Visit_U_1  1175    489   5     2018-07-30
9            Visit_U_1  2128    770   5     2019-01-08

我们可以看到查询结果,我们没有必要为构建id有三条记录,它可以是3,4或任意次。同样GregorianDates不固定。

我想像BuildingId'7'一样更新VisitNumbr序列。第一次访问必须是'Visit_U_1',而第二次访问必须是'Visit_U_2',根据GregorianDate。

同样建筑'8'。根据GregorianDate,访问号码再次变为“Visit_U_1”,“Visit_U_2”等。

sql-server loops sql-update sql-server-2014
2个回答
1
投票

我猜列'Gregorian Date'是一个DateTime数据类型字段。如果是这样,以下查询将满足您的目的 -

UPDATE V
SET    VisitNumber  = 'Visit_U_' + N
FROM   visit V
INNER JOIN (
    SELECT 
    BuildingId,
    GregorianDate,
    CAST(ROW_NUMBER() OVER(PARTITION BY BuildingID ORDER BY GregorianDate) AS VARCHAR) N
    FROM   visit
    WHERE  BuildingId IN (7, 8, 9,10)
    AND  status=5
) VN
ON  V. BuildingId = VN.BuildingId
AND V. GregorianDate = VN.GregorianDate
WHERE  V.BuildingId IN (7, 8, 9,10)
AND  V.status=5

注意:要生成row_number(),您需要在GregorianDate字段上按方法应用顺序。此字段中较小的值表示与下一个/后一个访问日期相比,访问号码应该是较小的一个。


0
投票

你可以使用substringrow_number来处理这个问题

选择查询

你想要输出如下Visit_U_1,Visit_U_2, Visit_U_3所以我从Vist列删除最后一位数字并将其与rownumber一起添加。这是使用Sunstringrow_number()函数完成的。将row_number转换为nvarchar以解决您获得的错误。

 substring(VisitNumber,0,len(VisitNumber)-1) + convert(nvarchar(50), row_number()over (partition by BuildingID order by BuildingID) ) visit_new

-

SELECT BuildingId,VisitNumber,Id,TasksId,Status,GregorianDate,row_number()over (partition by BuildingID order by BuildingID)srno,
substring(VisitNumber,0,len(VisitNumber)-1) + row_number()over (partition by BuildingID order by BuildingID) visit_new
FROM Visit 
where status=5 
and BuildingId in (7,8,9,10)
Group by BuildingId,Id,TasksId,Status,VisitNumber,GregorianDate
order by BuildingId,GregorianDate asc

更新查询

Update Visit
set Visit.VisitNumber = a.visit_new
FROM Visit 
inner join (
            SELECT   BuildingId,VisitNumber,Id,TasksId,Status,GregorianDate,row_number()over (partition by BuildingID order by GregorianDate )srno,
                     substring(VisitNumber,0,len(VisitNumber)-1) + convert(nvarchar(50), row_number()over (partition by BuildingID order by GregorianDate) )
            FROM     Visit  
            where    status=5 
            and      BuildingId in (7,8,9,10)
) a on a.status = Visit.status and a.BuildingId = visit.BuildingId
where status=5 
and BuildingId in (7,8,9,10)

在更新实时数据之前测试此代码。

© www.soinside.com 2019 - 2024. All rights reserved.