source

SQL Server: ORDER BY를 사용하여 테이블 업데이트

itover 2023. 8. 5. 22:39
반응형

SQL Server: ORDER BY를 사용하여 테이블 업데이트

테이블 업데이트 시 조항별 주문을 사용할 수 있는 방법이 있는지 알고 싶습니다.나는 표를 업데이트하고 연속적인 숫자를 설정하고 있기 때문에 업데이트 순서가 중요합니다.다음 sql 문을 사용하여 커서를 사용하지 않고 해결할 수 있었습니다.

DECLARE @Number INT = 0

UPDATE Test
SET @Number = Number = @Number +1

이제 제가 하고 싶은 것은 다음과 같은 조항별 주문은 다음과 같습니다.

 DECLARE @Number INT = 0

 UPDATE Test
 SET @Number = Number = @Number +1
 ORDER BY Test.Id DESC

읽은 적이 있습니다.msql을 사용하여 업데이트 주문하는 방법 이 질문에 대한 솔루션은 주문 문제를 해결하지 않습니다. 업데이트가 적용되는 항목을 필터링할 입니다.

몸조심해, 마틴

아니요.

문서화된 100% 지원 방법이 아닙니다."quirky update"라고 하는 실행 총계를 계산하는 데 사용되는 접근 방식이 있는데, 특정 조건이 충족되면 클러스터된 인덱스의 순서대로 업데이트할 수 있지만 제가 알기로는 이는 보증보다는 경험적 관찰에 전적으로 의존합니다.

하지만 현재 어떤 버전의 SQL Server를 사용하고 계십니까? 2005를 사용하면 SQL 2005+를 사용하여 할 수 .row_number 업데이트 및 CTE(CTE 를트수있습다니할데이

With cte As
(
SELECT id,Number,
ROW_NUMBER() OVER (ORDER BY id DESC) AS RN
FROM Test
)
UPDATE cte SET Number=RN

ORDER BY는 업데이트 문의 일부로 사용할 수 없습니다(업데이트의 일부인 하위 선택 항목에서 사용할 수 있음).

UPDATE Test 
SET Number = rowNumber 
FROM Test
INNER JOIN 
(SELECT ID, row_number() OVER (ORDER BY ID DESC) as rowNumber
FROM Test) drRowNumbers ON drRowNumbers.ID = Test.ID

편집

다음 솔루션은 여기에 언급된 대로 클러스터된 인덱스에 문제가 있을 수 있습니다.이것을 지적해 준 마틴에게 감사드립니다.

SQL Server의 모든 부작용이나 문제점을 잘 모르는 사람들(저와 같은)을 교육하기 위한 해답입니다.


당신의 링크에서 Quassnoi가 제공한 답변에 대해 다음 작업을 확장합니다.

DECLARE @Test TABLE (Number INTEGER, AText VARCHAR(2), ID INTEGER)
DECLARE @Number INT

INSERT INTO @Test VALUES (1, 'A', 1)
INSERT INTO @Test VALUES (2, 'B', 2)
INSERT INTO @Test VALUES (1, 'E', 5)
INSERT INTO @Test VALUES (3, 'C', 3)
INSERT INTO @Test VALUES (2, 'D', 4)

SET @Number = 0

;WITH q AS (
    SELECT  TOP 1000000 *
    FROM    @Test
    ORDER BY
            ID
)            
UPDATE  q
SET     @Number = Number = @Number + 1

row_number() 함수가 이 문제에 가장 적합한 방법입니다.

UPDATE T
    SET T.Number = R.rowNum
    FROM Test T
    JOIN (
        SELECT T2.id,row_number() over (order by T2.Id desc) rowNum from Test T2
    ) R on T.id=R.id 

SQL IN() 절의 값 순서에 따른 업데이트

솔루션:

DECLARE @counter int
SET @counter = 0

;WITH q  AS
        (
select * from Products WHERE ID in (SELECT TOP (10) ID FROM Products WHERE  ID IN( 3,2,1) 
ORDER BY ID DESC)
        )
update q set Display= @counter, @counter = @counter + 1

이 업데이트는 내림차순 3,2,1을 기준으로 합니다.

희망은 누군가를 돕습니다.

저도 비슷한 문제가 있었고 OVER 키워드와 함께 ROW_NUMBER()를 사용하여 해결했습니다.이 작업은 원래 작성된 날짜를 기준으로 간단한 표에 새 티켓 번호(정수) 필드를 소급하여 채우고 모듈 ID로 그룹화하여 각 모듈 그룹 내에서 티켓 번호가 1로 시작하여 날짜별로 증가하도록 하는 것이었습니다.테이블에 이미 티켓이 있습니다.ID 기본 키(GUID).

SQL은 다음과 같습니다.

UPDATE Tickets SET TicketNo=T2.RowNo
FROM Tickets
INNER JOIN 
  (select TicketID, TicketNo, 
     ROW_NUMBER() OVER (PARTITION BY ModuleId ORDER BY DateCreated) AS RowNo from Tickets) 
  AS T2 ON T2.TicketID = Tickets.TicketID

아주 잘 했어요!

저는 같은 문제에 부딪혔고 무한정 정렬이 가능한 매우 강력한 방법으로 해결할 수 있었습니다.

(저장) 2개의 정렬 순서를 사용하여 보기를 만들었습니다(*아래의 방법 설명).

그런 다음 업데이트 쿼리를 생성된 보기에 적용하면 잘 작동합니다.

다음은 보기에서 사용한 두 가지 쿼리입니다.

첫 번째 쿼리:

Update  MyView
Set SortID=0


두 번째 질문:

DECLARE @sortID int
SET     @sortID = 0
UPDATE  MyView
SET     @sortID = sortID = @sortID + 1


*보기에서 정렬을 저장할 수 있도록 TOP을 SELECT 문에 넣었습니다.이 매우 유용한 해결 방법을 사용하면 보기를 열 때 보기를 만들 때 보기 결과를 설정대로 정렬하여 반환할 수 있습니다.제 경우에는 다음과 같이 보였습니다.

(참고: 이 해결 방법을 사용하면 큰 테이블을 사용할 경우 서버에 큰 부하가 걸리므로 큰 테이블로 작업할 경우 보기에 가능한 한 적은 수의 필드를 포함하는 것이 좋습니다.)

SELECT     TOP (600000) 
dbo.Items.ID, dbo.Items.Code, dbo.Items.SortID, dbo.Supplier.Date, 
dbo.Supplier.Code AS Expr1
FROM         dbo.Items INNER JOIN
                      dbo.Supplier ON dbo.Items.SupplierCode = dbo.Supplier.Code
ORDER BY dbo.Supplier.Date, dbo.Items.ID DESC



실행 중: 윈도우즈 Server 2003에서 SQL Server 2005

추가 키워드:오름차순 또는 내림차순 숫자로 SQL 열을 업데이트하는 방법 - 숫자 값 / SQL 업데이트 문에서 순서를 설정하는 방법 / sql 보기에서 순서를 저장하는 방법 / increment sql update / auto increment sql update / sql 필드를 오름차순 숫자로 생성

SET @pos := 0;
UPDATE TABLE_NAME SET Roll_No = ( SELECT @pos := @pos + 1 ) ORDER BY First_Name ASC;

위의 예제 쿼리에서는 학생 Frist_Name 열에 따라 학생 Roll_No 열을 업데이트하기만 하면 됩니다.표의 1부터 No_of_records까지입니다.이제 확실해 졌으면 좋겠어요.

IF OBJECT_ID('tempdb..#TAB') IS NOT NULL
BEGIN
    DROP TABLE #TAB
END

CREATE TABLE #TAB(CH1 INT,CH2 INT,CH3 INT)

DECLARE @CH2 INT = NULL , @CH3 INT=NULL,@SPID INT=NULL,@SQL NVARCHAR(4000)='', @ParmDefinition NVARCHAR(50)= '',
@RET_MESSAGE AS VARCHAR(8000)='',@RET_ERROR INT=0


SET @ParmDefinition='@SPID INT,@CH2 INT OUTPUT,@CH3 INT OUTPUT'

SET @SQL='UPDATE T
            SET CH1=@SPID,@CH2= T.CH2,@CH3= T.CH3
            FROM #TAB T WITH(ROWLOCK)
            INNER JOIN (
                        SELECT TOP(1)  CH1,CH2,CH3
                        FROM
                        #TAB WITH(NOLOCK)
                        WHERE CH1 IS NULL
                        ORDER BY CH2 DESC) V ON T.CH2= V.CH2 AND T.CH3= V.CH3' 

INSERT INTO #TAB
(CH2 ,CH3 )
SELECT 1,2 UNION ALL
SELECT 2,3 UNION ALL
SELECT 3,4

BEGIN TRY
    WHILE EXISTS(SELECT TOP 1 1 FROM #TAB WHERE CH1 IS NULL)
    BEGIN

        EXECUTE @RET_ERROR = sp_executesql @SQL, @ParmDefinition,@SPID =@@SPID,  @CH2=@CH2 OUTPUT,@CH3=@CH3 OUTPUT;  

        SELECT * FROM #TAB
        SELECT @CH2,@CH3

    END

END TRY
BEGIN CATCH

    SET @RET_ERROR=ERROR_NUMBER()
    SET @RET_MESSAGE =  '@ERROR_NUMBER : ' + CAST(ERROR_NUMBER()  AS VARCHAR(255)) + '@ERROR_SEVERITY  :' + CAST( ERROR_SEVERITY()  AS VARCHAR(255)) 
    + '@ERROR_STATE :' + CAST(ERROR_STATE() AS VARCHAR(255)) + '@ERROR_LINE :' + CAST( ERROR_LINE() AS VARCHAR(255)) 
    +  '@ERROR_MESSAGE :' + ERROR_MESSAGE()  ;

    SELECT @RET_ERROR,@RET_MESSAGE;

END CATCH

언급URL : https://stackoverflow.com/questions/3439110/sql-server-update-a-table-by-using-order-by

반응형