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

时间:2019-04-25 06:37:02

标签: sql-server loops sql-update sql-server-2014

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

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

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或任意多次。同样,GregorianDate也不固定。

我想更新VisitNumbr序列,例如在BuildingId为'7'的情况下。根据GregorianDate,它的第一次访问必须是“ Visit_U_1”,第二次访问是“ Visit_U_2”等等。

类似地用于构建'8'。根据GregorianDate,访问号码再次变为“ Visit_U_1”,“ Visit_U_2”,等等。

2 个答案:

答案 0 :(得分:1)

我猜'GregorianDate'列是一个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字段中按方法应用订单。此字段中的值较小,表示访问次数应比下一个/以后的访问日期少。

答案 1 :(得分:0)

您可以使用substringrow_number

处理此问题

选择查询

您要输出如下Visit_U_1,Visit_U_2, Visit_U_3,因此我要从Vist列中删除最后一位数字,并将其与行号相加。这是通过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)
  

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