web-dev-qa-db-ja.com

SQL Serverのサブクエリを使用してクエリを更新する

このような単純なテーブル構造があります:

テーブルtempData

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

また、tempDataViewのような別のテーブル名もあります

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

テーブルを更新したいtempDataViewtempDataViewに応じてMarksを設定して、nameと比較- tempData-名前

はい、私が試したことを見せてください、カーソルを使用してこれを解決しようとしましたが、完全に解決しましたが、Subqueryを使用して解決する方法を見つけています

ここにあります:

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

実際、サブクエリを使用して解決するのは宿題のようなものです。

60
Narendra Pal

UPDATEステートメントでも両方のテーブルを結合できます。

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

パフォーマンスを高速化するには、両方のテーブルの列INDEXmarksを定義します。

SUBQUERYを使用

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

学習しているだけなので、SELECT結合をUPDATEまたはDELETE結合に変換することをお勧めします。最初に、これら2つのテーブルを結合するSELECTステートメントを生成することをお勧めします。

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

次に、2つのテーブルエイリアスaおよびbがあることに注意してください。これらのエイリアスを使用すると、テーブル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を遊び場として使用できます

29
cha

ここ は、いくつかの例を使用した更新操作のわかりやすい説明です。 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が一意のキーでない場合、2番目のクエリでは予期しない結果が生じる可能性がありますが、最初のクエリでは、一致するIDが複数ある場合にエラーが発生します。また、特定のaccounts.sales_idエントリに一致するものがない場合、最初のクエリは対応する名前フィールドをNULLに設定しますが、2番目のクエリはその行をまったく更新しません。

したがって、この例では、最も信頼できるクエリは次のようになります。

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

このスレッドのタイトルは、更新でサブクエリを使用する方法を尋ねます。以下に例を示します。

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
0
Graham Laight