[sql] SQL Server에서 하위 쿼리를 사용하여 쿼리 업데이트

다음과 같은 간단한 테이블 구조가 있습니다.

테이블 tempData

╔══════════╦═══════╗
║   NAME   ║ MARKS ║
╠══════════╬═══════╣
║ Narendra ║    80 ║
║ Ravi     ║    85 ║
║ Sanjay   ║    90 ║
╚══════════╩═══════╝

그리고 이와 같은 tempDataView 와 같은 다른 테이블 이름도 있습니다.

╔══════════╦═══════╗
║   NAME   ║ MARKS ║
╠══════════╬═══════╣
║ Narendra ║       ║
║ Narendra ║       ║
║ Narendra ║       ║
║ Narendra ║       ║
║ Ravi     ║       ║
║ Ravi     ║       ║
║ Sanjay   ║       ║
╚══════════╩═══════╝

나는 테이블 업데이트 할 tempDataView를 설정에 따라, 마크 받는 사람에 따라 tempDataView을이름 에 비해 tempData이름

예, 내가 시도한 것을 보여 드리겠습니다. 커서를 사용 하여이 문제를 해결하려고 시도했으며 완벽하게 해결되었지만 하위 쿼리를 사용하여 해결하는 방법을 찾고 있습니다.

여기있어:

Declare @name varchar(50),@marks varchar(50)
Declare @cursorInsert CURSOR
set @cursorInsert = CURSOR FOR
Select name,marks from tempData
OPEN @cursorInsert
FETCH NEXT FROM @cursorInsert
into @name,@marks
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE tempDataView set marks = @marks where name = @name
FETCH NEXT FROM @cursorInsert
INTO @name,@marks
END
CLOSE @cursorInsert
DEALLOCATE @cursorInsert

실제로 Subquery를 사용하여 해결하는 것은 숙제와 같습니다.



답변

UPDATE명령문 에서도 두 테이블을 결합 할 수 있습니다 .

UPDATE  a
SET     a.marks = b.marks
FROM    tempDataView a
        INNER JOIN tempData b
            ON a.Name = b.Name

더 빠른 성능을 위해 두 테이블 모두 INDEX에 on 열 marks을 정의하십시오 .

사용 SUBQUERY

UPDATE  tempDataView
SET     marks =
        (
          SELECT marks
          FROM tempData b
          WHERE tempDataView.Name = b.Name
        )


답변

방금 배우고 있기 때문에 SELECT 조인을 UPDATE 또는 DELETE 조인으로 변환하는 연습을하는 것이 좋습니다. 먼저 다음 두 테이블을 결합하는 SELECT 문을 생성하는 것이 좋습니다.

SELECT *
FROM    tempDataView a
        INNER JOIN tempData b
            ON a.Name = b.Name

그런 다음 두 개의 테이블 별칭 ab. 이러한 별칭을 사용하면 테이블 a 또는 b를 업데이트하는 UPDATE 문을 쉽게 생성 할 수 있습니다. 테이블 a의 경우 JW에서 제공 한 답변이 있습니다. 을 업데이트하려는 경우 b문은 다음과 같습니다.

UPDATE  b
SET     b.marks = a.marks
FROM    tempDataView a
        INNER JOIN tempData b
            ON a.Name = b.Name

이제 문을 DELETE 문으로 변환하려면 동일한 접근 방식을 사용하십시오. 아래 문 a은 이름으로 일치하는 레코드에 대해서만 (b 그대로 유지) 삭제합니다 .

DELETE a
FROM    tempDataView a
        INNER JOIN tempData b
            ON a.Name = b.Name

JW에서 만든 SQL Fiddle을 플레이 그라운드로 사용할 수 있습니다.


답변

여기 내 샘플에서 업데이트 및 하위 쿼리에 동일한 문제가 있었기 때문에 이에 대한 해결책을 찾습니다.

UPDATE
    A
SET
    A.ValueToChange = B.NewValue
FROM
    (
        Select * From C
    ) B
Where
    A.Id = B.Id


답변

이 스레드의 제목은 업데이트에서 하위 쿼리를 사용할 수있는 방법을 묻습니다. 여기에 그 예가 있습니다.

update [dbName].[dbo].[MyTable]
set MyColumn = 1
where
    (
        select count(*)
        from [dbName].[dbo].[MyTable] mt2
        where
            mt2.ID > [dbName].[dbo].[MyTable].ID
            and mt2.Category = [dbName].[dbo].[MyTable].Category
    ) > 0


답변

다음 은 몇 가지 예제와 함께 업데이트 작업에 대한 멋진 설명입니다. Postgres 사이트이지만 SQL 쿼리는 다른 DB에서도 유효합니다. 다음 예제는 이해하기 쉽습니다.

-- Update contact names in an accounts table to match the currently assigned salesmen:

UPDATE accounts SET (contact_first_name, contact_last_name) =
    (SELECT first_name, last_name FROM salesmen
     WHERE salesmen.id = accounts.sales_id);

-- A similar result could be accomplished with a join:

UPDATE accounts SET contact_first_name = first_name,
                    contact_last_name = last_name
  FROM salesmen WHERE salesmen.id = accounts.sales_id;

그러나 두 번째 쿼리는 salesmen.id가 고유 키가 아닌 경우 예기치 않은 결과를 제공 할 수있는 반면 첫 번째 쿼리는 일치하는 ID가 여러 개인 경우 오류를 발생시킵니다. 또한 특정 accounts.sales_id 항목과 일치하는 항목이없는 경우 첫 번째 쿼리는 해당 이름 필드를 NULL로 설정하는 반면 두 번째 쿼리는 해당 행을 전혀 업데이트하지 않습니다.

따라서 주어진 예에서 가장 신뢰할 수있는 쿼리는 다음과 같습니다.

UPDATE tempDataView SET (marks) =
    (SELECT marks FROM tempData
     WHERE tempDataView.Name = tempData.Name);


답변