it-swarm.com.de

Wie durchlaufe ich eine Tabelle und aktualisiere ein Feld in SQL

Ich muss eine Spalte mit einer fortlaufenden Nummer aktualisieren, die mit 1 beginnt, basierend auf dem accountId in der Tabelle. Wie mache ich das?

also ist OrderIDNULL, um zu beginnen. Daher muss ich für jede Zeile von AccountID das OrderID aktualisieren, um bei 1 zu beginnen, und nacheinander aktualisieren, damit meine Daten so ausgegeben werden. Die Tabelle heißt Renewals

RowID  AccountID  OrderID
1      A          1
2      A          2
4      A          3
5      B          1
6      B          2
7      C          1
5

Verwenden eines allgemeiner Tabellenausdruck mit row_number() zum Partitionieren nach AccountId und bestellen nach [RowId]:

;with cte as (
  select *
    ,  NewOrderId = row_number() over (
          partition by AccountId
          order by [RowId]
    )
  from Renewals
)
update cte
  set OrderId = NewOrderId;

Ohne den allgemeinen Tabellenausdruck zu verwenden:

update r
  set OrderId = NewOrderId
  from (
    select *
      ,  NewOrderId = row_number() over (
            partition by AccountId
            order by [RowId]
      )
    from Renewals
      ) as r

testaufbau: http://rextester.com/FSUD49402

create table Renewals (
    [RowId]   int     not null
  , AccountId char(1) not null
  , OrderId   int         null
);
insert into Renewals (RowId, AccountId) values
  (1,'A'), (2,'A'), (4,'A')
, (5,'B'), (6,'B'), (7,'C');

with cte as (
  select 
       [RowId]
    ,  AccountId
    ,  OrderId
    ,  NewOrderId = row_number() over (
          partition by AccountId
          order by [RowId]
    )
  from Renewals
)

update cte
  set OrderId = NewOrderId;

select * from Renewals;

ergebnisse in:

+-------+-----------+---------+
| RowId | AccountId | OrderId |
+-------+-----------+---------+
|     1 | A         |       1 |
|     2 | A         |       2 |
|     4 | A         |       3 |
|     5 | B         |       1 |
|     6 | B         |       2 |
|     7 | C         |       1 |
+-------+-----------+---------+

Um die Frage im Kommentar dieser Antwort zu beantworten:

Ich verwende diese Daten, um die vorherige Zeile zu aktualisieren. [...] Ich versuche zu zeigen, dass Zeile 1 oben durch Zeile 2 durch Zeile 4 ersetzt wurde und Zeile 4 noch nicht erneuert wurde

Kann gemacht werden mit:

select 
    r.*
  , RenewedBy=p.RowId 
from Renewals as r 
  left join Renewals as p 
    on p.AccountId = r.AccountId 
   and p.OrderId = r.OrderId+1

kehrt zurück:

+-------+-----------+---------+-----------+
| RowId | AccountId | OrderId | RenewedBy |
+-------+-----------+---------+-----------+
|     1 | A         |       1 | 2         |
|     2 | A         |       2 | 4         |
|     4 | A         |       3 | NULL      |
|     5 | B         |       1 | 6         |
|     6 | B         |       2 | NULL      |
|     7 | C         |       1 | NULL      |
+-------+-----------+---------+-----------+

Wenn dies der einzige Grund für das vorherige update ist, müssen wir die Tabelle überhaupt nicht update. Dies führt zu den gleichen Ergebnissen wie oben:

;with cte as (
  select *
    ,  rn = row_number() over (
          partition by AccountId
          order by [RowId]
    )
  from Renewals
)
select 
    r.RowId
  , r.AccountId
  , OrderId = r.rn
  , RenewedBy=p.RowId 
from cte as r 
  left join cte as p 
    on p.AccountId = r.AccountId 
   and p.rn = r.rn+1
8
SqlZim

Funktioniert das für Sie?

set nocount on
Declare @Renewals table (RowId int, AccountId varchar(10), OrderId int)

insert into @Renewals (RowId, AccountId, OrderId) values (1,'A',null)
insert into @Renewals (RowId, AccountId, OrderId) values (2,'A',null)
insert into @Renewals (RowId, AccountId, OrderId) values (4,'A',null)
insert into @Renewals (RowId, AccountId, OrderId) values (5,'B',null)
insert into @Renewals (RowId, AccountId, OrderId) values (6,'B',null)
insert into @Renewals (RowId, AccountId, OrderId) values (7,'C',null)

UPDATE a
SET OrderId = (
        SELECT count(*) + 1
        FROM @Renewals
        WHERE AccountId = a.AccountId
            AND RowId < a.RowId
        )
FROM @Renewals a

SELECT *
FROM @Renewals
0
Scott Hodgin

Sie können einfach eine Ansicht erstellen
Es ist effizient und Sie müssen die Erneuerung nicht mit Änderungen aktualisieren

create view vvv
as 
( select [RowId], [AccountId] 
       , row_number() over (partition by [AccountId] order by [RowId]) as [OrderId]
  from [Renewals] 
)

select * from vvv
0
paparazzo