programing

row_number()를 사용한SQL 업데이트

yoursource 2023. 4. 7. 22:45
반응형

row_number()를 사용한SQL 업데이트

제 컬럼 CODE_DEST를 증분 번호로 업데이트하고 싶습니다.다음과 같은 것이 있습니다.

CODE_DEST   RS_NOM
null        qsdf
null        sdfqsdfqsdf
null        qsdfqsdf

다음과 같이 업데이트하고 싶습니다.

CODE_DEST   RS_NOM
1           qsdf
2           sdfqsdfqsdf
3           qsdfqsdf

이 코드를 사용해 보았습니다.

UPDATE DESTINATAIRE_TEMP
SET CODE_DEST = TheId 
FROM (SELECT  Row_Number()   OVER (ORDER BY [RS_NOM]) AS TheId FROM DESTINATAIRE_TEMP)

이것은, 다음의 이유로 동작하지 않습니다.)

나도 시도해봤어:

WITH DESTINATAIRE_TEMP AS
  (
    SELECT 
    ROW_NUMBER() OVER (ORDER BY [RS_NOM] DESC) AS RN
    FROM DESTINATAIRE_TEMP
  )
UPDATE DESTINATAIRE_TEMP SET CODE_DEST=RN

하지만 이것 또한 조합 때문에 효과가 없다.

를 사용하여 열을 업데이트하려면ROW_NUMBER()SQL Server 2008 R2에서 작동합니까?

옵션 1개 추가

UPDATE x
SET x.CODE_DEST = x.New_CODE_DEST
FROM (
      SELECT CODE_DEST, ROW_NUMBER() OVER (ORDER BY [RS_NOM]) AS New_CODE_DEST
      FROM DESTINATAIRE_TEMP
      ) x
DECLARE @id INT 
SET @id = 0 
UPDATE DESTINATAIRE_TEMP
SET @id = CODE_DEST = @id + 1 
GO 

이거 먹어봐

http://www.mssqltips.com/sqlservertip/1467/populate-a-sql-server-column-with-a-sequential-number-not-using-an-identity/

With UpdateData  As
(
SELECT RS_NOM,
ROW_NUMBER() OVER (ORDER BY [RS_NOM] DESC) AS RN
FROM DESTINATAIRE_TEMP
)
UPDATE DESTINATAIRE_TEMP SET CODE_DEST = RN
FROM DESTINATAIRE_TEMP
INNER JOIN UpdateData ON DESTINATAIRE_TEMP.RS_NOM = UpdateData.RS_NOM

두 번째 시도는 기본적으로 CTE에 기본 테이블과 동일한 이름을 붙이고 CTE가 기본적으로 자신을 참조하기 때문에 재귀적인 CTE인 것처럼 보이게 했기 때문에 실패했습니다.재귀적 CTE는 특정 구조를 가지고 있어야 합니다.UNION ALLset 연산자

대신 CTE에 다른 이름을 붙이고 타깃컬럼을 추가할 수도 있습니다.

With SomeName As
(
SELECT 
CODE_DEST,
ROW_NUMBER() OVER (ORDER BY [RS_NOM] DESC) AS RN
FROM DESTINATAIRE_TEMP
)
UPDATE SomeName SET CODE_DEST=RN

이것은 WHERE 절을 추가한 @Alexandr Fedorenko의 답변의 수정 버전입니다.

UPDATE x
SET x.CODE_DEST = x.New_CODE_DEST
FROM (
      SELECT CODE_DEST, ROW_NUMBER() OVER (ORDER BY [RS_NOM]) AS New_CODE_DEST
      FROM DESTINATAIRE_TEMP
      ) x
WHERE x.CODE_DEST <> x.New_CODE_DEST AND x.CODE_DEST IS NOT NULL

WHERE 조항을 추가함으로써 후속 업데이트를 위해 성능이 크게 향상되었습니다.SQL Server는 값이 이미 존재하여 업데이트에 시간이 걸리기 때문에 where 구를 추가하면 값이 변경되지 않은 행을 건너뜁니다.나는 그것이 나의 질문을 얼마나 빨리 실행할 수 있는지 놀랐다고 말해야겠다.

면책사항:저는 DB 전문가가 아니며, 이 조항에 대해 파티션 BY를 사용하고 있기 때문에 이 쿼리에 대한 결과가 완전히 동일하지 않을 수 있습니다.저에게 있어서, 문제의 열은 고객의 유료 주문이기 때문에, 일반적으로 한번 설정해도 값은 변하지 않습니다.

또한 SELECT 문에 WHERE 절이 있는 경우 인덱스가 있는지 확인하십시오.지불 상황을 기준으로 필터링을 하고 있었기 때문에 필터링된 인덱스가 매우 효과가 있었습니다.


파티셔닝을 사용한 내 쿼리:

UPDATE  UpdateTarget
SET     PaidOrderIndex = New_PaidOrderIndex
FROM
(
    SELECT  PaidOrderIndex, SimpleMembershipUserName, ROW_NUMBER() OVER(PARTITION BY SimpleMembershipUserName ORDER BY OrderId) AS New_PaidOrderIndex
    FROM    [Order]
    WHERE   PaymentStatusTypeId in (2,3,6) and SimpleMembershipUserName is not null
) AS UpdateTarget

WHERE UpdateTarget.PaidOrderIndex <> UpdateTarget.New_PaidOrderIndex AND UpdateTarget.PaidOrderIndex IS NOT NULL

-- test to 'break' some of the rows, and then run the UPDATE again
update [order] set PaidOrderIndex = 2 where PaidOrderIndex=3

열이 NULL이 아닌 경우 'IS NOT NULL' 부분은 필요하지 않습니다.


퍼포먼스가 대폭 향상되었다고 하는 것은 소수의 행을 갱신했을 때 본질적으로 즉시 증가했다는 것을 의미합니다.적절한 인덱스를 사용하여 '내부' 쿼리가 자체적으로 수행하는 것과 동일한 시간이 소요되는 업데이트를 수행할 수 있었습니다.

  SELECT  PaidOrderIndex, SimpleMembershipUserName, ROW_NUMBER() OVER(PARTITION BY SimpleMembershipUserName ORDER BY OrderId) AS New_PaidOrderIndex
    FROM    [Order]
    WHERE   PaymentStatusTypeId in (2,3,6) and SimpleMembershipUserName is not null

나는 내 상황을 위해 이것을 했고 일을 했다.

WITH myUpdate (id, myRowNumber )
AS
( 
    SELECT id, ROW_NUMBER() over (order by ID) As myRowNumber
    FROM AspNetUsers
    WHERE  UserType='Customer' 
 )

update AspNetUsers set EmployeeCode = FORMAT(myRowNumber,'00000#') 
FROM myUpdate
    left join AspNetUsers u on u.Id=myUpdate.id

쉽고 간단한 커서 업데이트 방법

UPDATE Cursor
SET Cursor.CODE = Cursor.New_CODE
FROM (
  SELECT CODE, ROW_NUMBER() OVER (ORDER BY [CODE]) AS New_CODE
  FROM Table Where CODE BETWEEN 1000 AND 1999
  ) Cursor

테이블에 관계가 없는 경우 행 번호가 있는 새 테이블에 모두 복사하고 오래된 테이블을 제거하고 새 테이블을 이전 테이블로 이름을 바꿉니다.

Select   RowNum = ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) , * INTO cdm.dbo.SALES2018 from 
(
select * from SALE2018) as SalesSource

내 경우 새 열을 추가하고 전체 테이블에 대해 equivalat 레코드 번호로 업데이트하기를 원했습니다.

id  name       new_column (ORDER_NUM)
1   Ali        null
2   Ahmad      null
3   Mohammad   null
4   Nour       null
5   Hasan      null
6   Omar       null

새 열에 행 번호를 입력하기 위해 이 쿼리를 작성했습니다.

UPDATE My_Table
SET My_Table.ORDER_NUM  = SubQuery.rowNumber
FROM (
         SELECT id ,ROW_NUMBER() OVER (ORDER BY [id]) AS rowNumber
         FROM My_Table
     ) SubQuery
INNER JOIN My_Table ON
        SubQuery.id = My_Table.id

이 쿼리를 실행한 후 나는 새 칼럼에 1,2,3,...의 숫자를 넣었다.

여러 부품을 시퀀스 번호와 연관지을 수 있는 첫 번째 부품으로 임시 테이블을 업데이트합니다.RowId=1은 tmp 테이블과 부품 및 시퀀스 번호를 사용하여 처음 발생한 데이터를 반환합니다.

update #Tmp
set 
#Tmp.Amount=@Amount
from 
(SELECT Part, Row_Number()   OVER (ORDER BY [Part]) AS RowId FROM #Tmp
where Sequence_Num=@Sequence_Num
)data
where data.Part=#Tmp.Part
and data.RowId=1
and #Tmp.Sequence_Num=@Sequence_Num

"Basheer AL-MOMANI"가 제안한 것을 실행하기 위한 실행 ID가 없습니다.다음과 같은 작업을 수행했습니다. (테이블에 직접 참여했습니다.줄 번호를 얻기 위해서입니다)

update T1 set inID = T2.RN
from (select *, ROW_NUMBER() over (order by ID) RN from MyTable) T1
    inner join (select *, ROW_NUMBER() over (order by ID) RN from MyTable) T2 on T2.RN = T1.RN

언급URL : https://stackoverflow.com/questions/13648898/sql-update-with-row-number

반응형