У меня есть простая структура таблицы:
Таблица tempData
╔══════════╦═══════╗
║ NAME ║ MARKS ║
╠══════════╬═══════╣
║ Narendra ║ 80 ║
║ Ravi ║ 85 ║
║ Sanjay ║ 90 ║
╚══════════╩═══════╝
И у меня также есть другие имена таблиц как tempDataView, например
╔══════════╦═══════╗
║ NAME ║ MARKS ║
╠══════════╬═══════╣
║ Narendra ║ ║
║ Narendra ║ ║
║ Narendra ║ ║
║ Narendra ║ ║
║ Ravi ║ ║
║ Ravi ║ ║
║ Sanjay ║ ║
╚══════════╩═══════╝
Я хочу обновить таблицу tempDataView , установив метки в соответствии с tempDataView - Name по сравнению с tempData - Name
Да, позвольте мне показать вам, что я пробовал, я пытался решить эту проблему с помощью курсора, и он решил отлично, но я нахожу способ решить эту проблему с помощью подзапроса
Вот:
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
На самом деле, решить эту проблему с помощью подзапроса для меня как домашнее задание.
sql
sql-server
tsql
sql-update
Нарендра Пал
источник
источник
subquery
, но я предпочитаю использоватьJOIN
чемSUBQUERY
.INDEX
поmarks
столбцам? Разве не наName
колоннах?SELECT
наSELECT TOP 1
поскольку вы только учитесь, я предлагаю вам попрактиковаться в преобразовании соединений SELECT в соединения UPDATE или DELETE. Сначала я предлагаю вам создать оператор SELECT, соединяющий эти две таблицы:
SELECT * FROM tempDataView a INNER JOIN tempData b ON a.Name = b.Name
Затем обратите внимание, что у нас есть два псевдонима таблиц
a
иb
. Используя эти псевдонимы, вы можете легко сгенерировать оператор UPDATE для обновления таблицы a или b. Для таблицы 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
Вы можете использовать SQL Fiddle, созданный JW, в качестве игровой площадки
источник
Здесь, в моем примере, я нахожу решение этой проблемы, потому что у меня была такая же проблема с обновлениями и подзапросами:
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 действительны и для других БД. Следующие ниже примеры интуитивно понятны.
-- 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 не является уникальным ключом, тогда как первый запрос гарантированно вызовет ошибку, если есть несколько совпадений идентификаторов. Кроме того, если для конкретной записи account.sales_id нет совпадения, первый запрос установит для соответствующих полей имени значение NULL, тогда как второй запрос вообще не обновит эту строку.
Следовательно, для данного примера наиболее надежный запрос выглядит следующим образом.
UPDATE tempDataView SET (marks) = (SELECT marks FROM tempData WHERE tempDataView.Name = tempData.Name);
источник