Как я могу ОБНОВИТЬ из SELECT в SQL Server?

В SQL Server можно insert в таблицу с помощью SELECT:

INSERT INTO Table (col1, col2, col3)
SELECT col1, col2, col3 
FROM other_table 
WHERE sql = 'cool'

Возможно ли также обновление через SELECT? У меня есть временная таблица, содержащая значения, и я хотел бы обновить другую таблицу, используя эти значения. Возможно, что-то вроде этого:

UPDATE Table SET col1, col2
SELECT col1, col2 
FROM other_table 
WHERE sql = 'cool'
WHERE Table.id = other_table.id
+3169
25 февр. '10 в 14:36
источник поделиться
32 ответа
  • 1
  • 2
UPDATE
    Table_A
SET
    Table_A.col1 = Table_B.col1,
    Table_A.col2 = Table_B.col2
FROM
    Some_Table AS Table_A
    INNER JOIN Other_Table AS Table_B
        ON Table_A.id = Table_B.id
WHERE
    Table_A.col3 = 'cool'
+4627
25 февр. '10 в 14:39
источник

В SQL Server 2008 (или лучше) используйте MERGE

MERGE INTO YourTable T
   USING other_table S 
      ON T.id = S.id
         AND S.tsql = 'cool'
WHEN MATCHED THEN
   UPDATE 
      SET col1 = S.col1, 
          col2 = S.col2;

В качестве альтернативы:

MERGE INTO YourTable T
   USING (
          SELECT id, col1, col2 
            FROM other_table 
           WHERE tsql = 'cool'
         ) S
      ON T.id = S.id
WHEN MATCHED THEN
   UPDATE 
      SET col1 = S.col1, 
          col2 = S.col2;
+691
09 сент. '11 в 9:40
источник
UPDATE table 
SET Col1 = i.Col1, 
    Col2 = i.Col2 
FROM (
    SELECT ID, Col1, Col2 
    FROM other_table) i
WHERE 
    i.ID = table.ID
+545
22 янв. '12 в 17:47
источник

Я бы изменил Робин отличный ответ на следующее:

UPDATE Table
SET Table.col1 = other_table.col1,
 Table.col2 = other_table.col2
FROM
    Table
INNER JOIN other_table ON Table.id = other_table.id
WHERE
    Table.col1 != other_table.col1
OR Table.col2 != other_table.col2
OR (
    other_table.col1 IS NOT NULL
    AND Table.col1 IS NULL
)
OR (
    other_table.col2 IS NOT NULL
    AND Table.col2 IS NULL
)

Без предложения WHERE вы будете влиять на четные строки, которые не должны быть затронуты, что может (возможно) вызвать перерасчет индекса или триггеры запуска, которые действительно не должны были быть запущены.

+256
08 сент. '11 в 21:20
источник

Один из способов

UPDATE t 
SET t.col1 = o.col1, 
    t.col2 = o.col2
FROM 
    other_table o 
  JOIN 
    t ON t.id = o.id
WHERE 
    o.sql = 'cool'
+184
25 февр. '10 в 14:41
источник

Еще одна возможность, о которой еще не упоминалось, состоит в том, чтобы просто вытолкнуть сам SELECT в CTE, а затем обновить CTE.

;WITH CTE
     AS (SELECT T1.Col1,
                T2.Col1 AS _Col1,
                T1.Col2,
                T2.Col2 AS _Col2
         FROM   T1
                JOIN T2
                  ON T1.id = T2.id
         /*Where clause added to exclude rows that are the same in both tables
           Handles NULL values correctly*/
         WHERE EXISTS(SELECT T1.Col1,
                             T1.Col2
                       EXCEPT
                       SELECT T2.Col1,
                              T2.Col2))
UPDATE CTE
SET    Col1 = _Col1,
       Col2 = _Col2

Это имеет то преимущество, что легко запустить SELECT самостоятельно, чтобы проверить работоспособность результатов, но для этого требуется, чтобы вы использовали псевдоним столбцов, как указано выше, если они названы одинаковыми в исходных и целевых таблицах.

Это также имеет те же ограничения, что и проприетарный синтаксис UPDATE... FROM показанный в четырех других ответах. Если исходная таблица находится на много сторон соединения "один-ко-многим", то неопределенно, какая из возможных сопоставленных объединенных записей будет использоваться в Update (проблема, которую MERGE избегает, вызывая ошибку, если есть попытка обновлять одну и ту же строку более одного раза).

+143
06 нояб. '11 в 0:18
источник

Для записи (и других, таких как я был), вы можете сделать это в MySQL следующим образом:

UPDATE first_table, second_table
SET first_table.color = second_table.color
WHERE first_table.id = second_table.foreign_id
+97
05 окт. '12 в 14:20
источник

Использование псевдонима:

UPDATE t
   SET t.col1 = o.col1
  FROM table1 AS t
         INNER JOIN 
       table2 AS o 
         ON t.id = o.id
+81
23 мая '12 в 13:06
источник

Простой способ сделать это:

UPDATE
    table_to_update,
    table_info
SET
    table_to_update.col1 = table_info.col1,
    table_to_update.col2 = table_info.col2

WHERE
    table_to_update.ID = table_info.ID
+62
14 нояб. '12 в 13:17
источник

Это может быть нишей причиной для выполнения обновления (например, в основном используется в процедуре), или может быть очевидным для других, но также следует указать, что вы можете выполнять инструкцию выбора выбора без использования соединения ( в случае, если таблицы, которые вы обновляете, не имеют общего поля).

update
    Table
set
    Table.example = a.value
from
    TableExample a
where
    Table.field = *key value* -- finds the row in Table 
    AND a.field = *key value* -- finds the row in TableExample a
+49
11 июн. '12 в 16:58
источник

Вот еще один полезный синтаксис:

UPDATE suppliers
SET supplier_name = (SELECT customers.name
                     FROM customers
                     WHERE customers.customer_id = suppliers.supplier_id)
WHERE EXISTS (SELECT customers.name
              FROM customers
              WHERE customers.customer_id = suppliers.supplier_id);

Он проверяет, является ли он нулевым или нет, используя "WHERE EXIST".

+48
02 мая '13 в 9:48
источник

Если вы используете MySQL вместо SQL Server, синтаксис следующий:

UPDATE Table1
INNER JOIN Table2
ON Table1.id = Table2.id
SET Table1.col1 = Table2.col1,
    Table1.col2 = Table2.col2
+45
03 окт. '13 в 13:16
источник

Я добавляю это только так, чтобы вы могли быстро просмотреть его, чтобы вы могли проверить, что будет обновляться до выполнения обновления.

UPDATE Table 
SET  Table.col1 = other_table.col1,
     Table.col2 = other_table.col2 
--select Table.col1, other_table.col,Table.col2,other_table.col2, *   
FROM     Table 
INNER JOIN     other_table 
    ON     Table.id = other_table.id 
+45
08 сент. '11 в 21:35
источник

UPDATE из SELECT с INNER JOIN в базе данных SQL

Поскольку слишком много ответов на этот пост, которые наиболее сильно опротестованы, я подумал, что также предлагаю свое предложение. Хотя вопрос очень интересный, я видел на многих сайтах форума и сделал решение, используя INNER JOIN со скриншотами.

Сначала я создал таблицу с именем schoolold и вставил несколько записей в отношении их имен столбцов и выполнил их.

Затем я выполнил команду SELECT для просмотра вставленных записей.

Затем я создал новую таблицу с именем schoolnew и аналогично выполнил над ней действия.

Затем, чтобы просмотреть вставленные записи в нем, я выполняю команду SELECT.

Теперь, здесь я хочу внести некоторые изменения в третью и четвертую строки, чтобы завершить это действие, я выполняю команду UPDATE с INNER JOIN.

Чтобы просмотреть изменения, я выполняю команду SELECT.

Вы можете видеть, как третья и четвертая записи школьного школьного стола легко заменяются таблицей schoolnew, используя INNER JOIN с инструкцией UPDATE.

+40
30 нояб. '15 в 5:48
источник

И если вы хотите присоединиться к таблице с собой (что не произойдет слишком часто):

update t1                    -- just reference table alias here
set t1.somevalue = t2.somevalue
from table1 t1               -- these rows will be the targets
inner join table1 t2         -- these rows will be used as source
on ..................        -- the join clause is whatever suits you
+35
27 июн. '14 в 21:14
источник

В следующем примере используется производная таблица, инструкция SELECT после предложения FROM, для возврата старых и новых значений для последующих обновлений:

UPDATE x
SET    x.col1 = x.newCol1,
       x.col2 = x.newCol2
FROM   (SELECT t.col1,
               t2.col1 AS newCol1,
               t.col2,
               t2.col2 AS newCol2
        FROM   [table] t
               JOIN other_table t2
                 ON t.ID = t2.ID) x
+33
25 сент. '13 в 6:18
источник

Обновление через CTE более читаемо, чем другие ответы здесь:

;WITH cte
     AS (SELECT col1,col2,id
         FROM   other_table
         WHERE  sql = 'cool')
UPDATE A
SET    A.col1 = B.col1,
       A.col2 = B.col2
FROM   table A
       INNER JOIN cte B
               ON A.id = B.id
+31
12 дек. '15 в 16:32
источник

Если вы используете SQL Server, вы можете обновить одну таблицу от другой без указания соединения и просто связать два из предложения where. Это делает гораздо более простой SQL-запрос:

UPDATE Table1
SET Table1.col1 = Table2.col1,
    Table1.col2 = Table2.col2
FROM
    Table2
WHERE
    Table1.id = Table2.id
+31
20 февр. '17 в 16:34
источник

Другим способом является использование производной таблицы:

UPDATE t
SET t.col1 = a.col1
    ,t.col2 = a.col2
FROM (
SELECT id, col1, col2 FROM @tbl2) a
INNER JOIN @tbl1 t ON t.id = a.id

Примеры данных

DECLARE @tbl1 TABLE (id INT, col1 VARCHAR(10), col2 VARCHAR(10))
DECLARE @tbl2 TABLE (id INT, col1 VARCHAR(10), col2 VARCHAR(10))

INSERT @tbl1 SELECT 1, 'a', 'b' UNION SELECT 2, 'b', 'c'

INSERT @tbl2 SELECT 1, '1', '2' UNION SELECT 2, '3', '4'

UPDATE t
SET t.col1 = a.col1
    ,t.col2 = a.col2
FROM (
SELECT id, col1, col2 FROM @tbl2) a
INNER JOIN @tbl1 t ON t.id = a.id

SELECT * FROM @tbl1
SELECT * FROM @tbl2
+19
24 февр. '16 в 23:35
источник
UPDATE TQ
SET TQ.IsProcessed = 1, TQ.TextName = 'bla bla bla'
FROM TableQueue TQ
INNER JOIN TableComment TC ON TC.ID = TQ.TCID
WHERE TQ.IsProcessed = 0

Чтобы убедиться, что вы обновляете то, что хотите, выберите первый

SELECT TQ.IsProcessed, 1 AS NewValue1, TQ.TextName, 'bla bla bla' AS NewValue2
FROM TableQueue TQ
INNER JOIN TableComment TC ON TC.ID = TQ.TCID
WHERE TQ.IsProcessed = 0
+19
30 нояб. '16 в 21:06
источник

Использование:

drop table uno
drop table dos

create table uno
(
    uid int,
    col1 char(1),
    col2 char(2)
)
create table dos
(
    did int,
    col1 char(1),
    col2 char(2),
    [sql] char(4)
)
insert into uno(uid) values (1)
insert into uno(uid) values (2)
insert into dos values (1,'a','b',null)
insert into dos values (2,'c','d','cool')

select * from uno 
select * from dos

ИЛИ:

update uno set col1 = (select col1 from dos where uid = did and [sql]='cool'), 
col2 = (select col2 from dos where uid = did and [sql]='cool')

ИЛИ ЖЕ:

update uno set col1=d.col1,col2=d.col2 from uno 
inner join dos d on uid=did where [sql]='cool'

select * from uno 
select * from dos

Если имя столбца ID одинаково в обеих таблицах, просто поместите имя таблицы перед обновлением таблицы и используйте псевдоним для выбранной таблицы, то есть:

update uno set col1 = (select col1 from dos d where uno.[id] = d.[id] and [sql]='cool'),
col2  = (select col2 from dos d where uno.[id] = d.[id] and [sql]='cool')
+16
18 июн. '14 в 11:40
источник

Существует даже более короткий метод, и это может вас удивить:

Пример набора данных:

CREATE TABLE #SOURCE ([ID] INT, [Desc] VARCHAR(10));
CREATE TABLE #DEST   ([ID] INT, [Desc] VARCHAR(10));

INSERT INTO #SOURCE VALUES(1,'Desc_1'), (2, 'Desc_2'), (3, 'Desc_3');
INSERT INTO #DEST   VALUES(1,'Desc_4'), (2, 'Desc_5'), (3, 'Desc_6');

Код:

UPDATE #DEST
SET #DEST.[Desc] = #SOURCE.[Desc]
FROM #SOURCE
WHERE #DEST.[ID] = #SOURCE.[ID];
+16
26 янв. '17 в 13:28
источник

Ниже приведенное решение работает для базы данных MySQL:

UPDATE table1 a , table2 b 
SET a.columname = 'some value' 
WHERE b.columnname IS NULL ;
+14
01 окт. '14 в 6:24
источник

Другой способ обновления из оператора select:

UPDATE A
SET A.col = A.col,B.col1 = B.col1
FROM  first_Table AS A
INNER JOIN second_Table AS B  ON A.id = B.id WHERE A.col2 = 'cool'
+13
08 сент. '16 в 12:02
источник

В принятом ответе после:

SET
Table_A.col1 = Table_B.col1,
Table_A.col2 = Table_B.col2

Я бы добавил:

OUTPUT deleted.*, inserted.*

То, что я обычно делаю, заключается в том, чтобы поместить все в транзакцию с резервными копиями и использовать "OUTPUT": таким образом я вижу все, что должно произойти. Когда я доволен тем, что вижу, я меняю ROLLBACK в COMMIT.

Мне обычно нужно документировать то, что я сделал, поэтому я использую параметр "results to Text" когда запускаю запрос с поддержкой roll-backed, и сохраняю как скрипт, так и результат OUTPUT. (Конечно, это непрактично, если я изменил слишком много строк)

+13
27 апр. '17 в 7:54
источник
UPDATE table AS a
INNER JOIN table2 AS b
ON a.col1 = b.col1
INNER JOIN ... AS ...
ON ... = ...
SET ...
WHERE ...
+12
31 июл. '15 в 8:04
источник

Здесь объединены все различные подходы.

  1. Выберите обновление
  2. Обновление с помощью общего выражения таблицы
  3. сливаться

Пример структуры таблицы ниже и будет обновляться из Product_BAK в таблицу Product.

Товар

CREATE TABLE [dbo].[Product](
    [Id] [int] IDENTITY(1, 1) NOT NULL,
    [Name] [nvarchar](100) NOT NULL,
    [Description] [nvarchar](100) NULL
) ON [PRIMARY]

Product_BAK

    CREATE TABLE [dbo].[Product_BAK](
        [Id] [int] IDENTITY(1, 1) NOT NULL,
        [Name] [nvarchar](100) NOT NULL,
        [Description] [nvarchar](100) NULL
    ) ON [PRIMARY]

1. Выберите обновление

    update P1
    set Name = P2.Name
    from Product P1
    inner join Product_Bak P2 on p1.id = P2.id
    where p1.id = 2

2. Обновление с использованием общего табличного выражения

    ; With CTE as
    (
        select id, name from Product_Bak where id = 2
    )
    update P
    set Name = P2.name
    from  product P  inner join CTE P2 on P.id = P2.id
    where P2.id = 2

3. Слияние

    Merge into product P1
    using Product_Bak P2 on P1.id = P2.id

    when matched then
    update set p1.[description] = p2.[description], p1.name = P2.Name;

В операторе Merge мы можем делать вставку, если не находим подходящую запись в целевом объекте, но существуем в источнике и находим синтаксис:

    Merge into product P1
    using Product_Bak P2 on P1.id = P2.id;

    when matched then
    update set p1.[description] = p2.[description], p1.name = P2.Name;

    WHEN NOT MATCHED THEN
    insert (name, description)
    values(p2.name, P2.description);
+7
31 янв. '18 в 15:42
источник

Вы можете использовать это для обновления на сервере sql

UPDATE
    T1
SET
   T1.col1 = T2.col1,
   T1.col2 = T2.col2
FROM
   Table1 AS T1
INNER JOIN Table2 AS T2
    ON T1.id = T2.id
WHERE
    T1.col3 = 'cool'
+1
31 авг. '18 в 16:48
источник
declare @tblStudent table (id int,name varchar(300))
declare @tblMarks table (std_id int,std_name varchar(300),subject varchar(50),marks int)

insert into @tblStudent Values (1,'Abdul')
insert into @tblStudent Values(2,'Rahim')

insert into @tblMarks Values(1,'','Math',50)
insert into @tblMarks Values(1,'','History',40)
insert into @tblMarks Values(2,'','Math',30)
insert into @tblMarks Values(2,'','history',80)


select * from @tblMarks

update m
set m.std_name=s.name
 from @tblMarks as m
left join @tblStudent as s on s.id=m.std_id

select * from @tblMarks
+1
08 окт. '18 в 12:22
источник
  1. Использование Inner Join

UPDATE A SET A.col1 = B.col1, A.col2 = B.col2 FROM Some_Table AS INNER JOIN Other_Table AS B ON A.id = B.id WHERE A.col3 = 'cool'

  1. Связанный с Sub запрос

Таблица UPDATE SET Col1 = B.Col1, Col2 = B.Col2 FROM (SELECT ID, Col1, Col2 FROM other_table) B WHERE B.ID = table.ID

0
07 нояб. '18 в 7:34
источник
  • 1
  • 2

Посмотрите другие вопросы по меткам или Задайте вопрос