Mam prostą strukturę tabeli, taką jak ta:
Tabela tempData
╔══════════╦═══════╗
║ NAME ║ MARKS ║
╠══════════╬═══════╣
║ Narendra ║ 80 ║
║ Ravi ║ 85 ║
║ Sanjay ║ 90 ║
╚══════════╩═══════╝
Mam też inne nazwy tabel, takie jak tempDataView
╔══════════╦═══════╗
║ NAME ║ MARKS ║
╠══════════╬═══════╣
║ Narendra ║ ║
║ Narendra ║ ║
║ Narendra ║ ║
║ Narendra ║ ║
║ Ravi ║ ║
║ Ravi ║ ║
║ Sanjay ║ ║
╚══════════╩═══════╝
Chcę zaktualizować tabelę tempDataView , ustawiając znaczniki zgodnie z tempDataView - Nazwa w porównaniu z tempData - Nazwa
Tak, pozwól, że pokażę ci, czego próbowałem, próbowałem rozwiązać to za pomocą kursora i zostało rozwiązane idealnie, ale znajduję sposób, aby rozwiązać to za pomocą podzapytania
Oto ona:
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
Właściwie to jak praca domowa, aby rozwiązać to za pomocą podzapytania.
sql
sql-server
tsql
sql-update
Narendra Pal
źródło
źródło
subquery
, ale wolę używaćJOIN
thanSUBQUERY
.INDEX
namarks
kolumnach? Czy nie powinno być naName
kolumnach?SELECT
naSELECT TOP 1
ponieważ dopiero się uczysz, proponuję przećwiczyć konwersję złączeń SELECT na złączenia UPDATE lub DELETE. Najpierw proponuję wygenerowanie instrukcji SELECT łączącej te dwie tabele:
SELECT * FROM tempDataView a INNER JOIN tempData b ON a.Name = b.Name
Następnie zauważ, że mamy dwa aliasy tabel
a
ib
. Korzystając z tych aliasów, można łatwo wygenerować instrukcję UPDATE w celu zaktualizowania tabeli a lub b. Do tabeli A masz odpowiedź udzieloną przez JW. Jeśli chcesz zaktualizowaćb
, wyciąg będzie:UPDATE b SET b.marks = a.marks FROM tempDataView a INNER JOIN tempData b ON a.Name = b.Name
Teraz, aby przekonwertować instrukcję na instrukcję DELETE, użyj tego samego podejścia. Poniższe stwierdzenie usunie
a
tylko z (pozostawiając b nienaruszone) dla tych rekordów, które pasują według nazwy:DELETE a FROM tempDataView a INNER JOIN tempData b ON a.Name = b.Name
Możesz użyć SQL Fiddle stworzonego przez JW jako placu zabaw
źródło
Tutaj w mojej próbce znajduję rozwiązanie tego, ponieważ miałem ten sam problem z aktualizacjami i podzapytaniami:
UPDATE A SET A.ValueToChange = B.NewValue FROM ( Select * From C ) B Where A.Id = B.Id
źródło
Tytuł tego wątku zawiera pytanie, w jaki sposób można użyć podzapytania w aktualizacji. Oto przykład:
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
źródło
Oto ładne wyjaśnienie operacji aktualizacji z kilkoma przykładami. Chociaż jest to witryna Postgres, ale zapytania SQL są poprawne również dla innych DB. Poniższe przykłady są intuicyjne do zrozumienia.
-- 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;
Jednak drugie zapytanie może dać nieoczekiwane wyniki, jeśli salesmen.id nie jest unikalnym kluczem, podczas gdy pierwsze zapytanie gwarantuje wygenerowanie błędu, jeśli istnieje wiele zgodnych identyfikatorów. Ponadto, jeśli nie ma dopasowania dla określonego wpisu accounts.sales_id, pierwsze zapytanie ustawi odpowiednie pola nazw na NULL, podczas gdy drugie zapytanie w ogóle nie zaktualizuje tego wiersza.
Dlatego dla podanego przykładu najbardziej wiarygodne zapytanie jest takie jak poniżej.
UPDATE tempDataView SET (marks) = (SELECT marks FROM tempData WHERE tempDataView.Name = tempData.Name);
źródło