Hoe kan ik UPDATE van een SELECT in SQL Server?

In SQL Serveris het mogelijk om rijen in een tabel in te voegen met een INSERT.. SELECT-instructie:

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

Is het ook mogelijk om een ​​tabel bij te werkenmet SELECT? Ik heb een tijdelijke tabel met de waarden en wil graag een andere tabel bijwerken met die waarden. Misschien zoiets als dit:

UPDATE Table SET col1, col2
SELECT col1, col2 
FROM other_table 
WHERE sql = 'cool'
WHERE Table.id = other_table.id

Antwoord 1, autoriteit 100%

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'

Antwoord 2, autoriteit 14%

Gebruik in SQL Server 2008 (of nieuwer) 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;

Alternatief:

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;

Antwoord 3, autoriteit 13%

UPDATE YourTable 
SET Col1 = OtherTable.Col1, 
    Col2 = OtherTable.Col2 
FROM (
    SELECT ID, Col1, Col2 
    FROM other_table) AS OtherTable
WHERE 
    OtherTable.ID = YourTable.ID

Antwoord 4, autoriteit 5%

Ik zou Robin’s uitstekend antwoordop het volgende:

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
)

Zonder een WHERE-clausule heb je invloed op zelfs rijen die niet hoeven te worden beïnvloed, wat (mogelijk) herberekening van de index of triggers kan veroorzaken die eigenlijk niet hadden moeten worden geactiveerd.


Antwoord 5, autoriteit 4%

Enkele reis

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'

Antwoord 6, autoriteit 3%

Een andere mogelijkheid die nog niet is genoemd, is om de SELECT-instructie zelf in een CTE te stoppen en vervolgens de CTE bij te werken.

;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

Dit heeft het voordeel dat het gemakkelijk is om eerst de SELECT-instructie alleen uit te voeren om de resultaten te controleren, maar het vereist wel dat u de kolommen zoals hierboven een alias geeft als ze dezelfde naam hebben in bron- en doeltabellen.

Dit heeft ook dezelfde beperking als de eigen UPDATE ... FROM-syntaxis die in vier van de andere antwoorden wordt getoond. Als de brontabel zich aan de veelkant van een één-op-veel-join bevindt, is het niet bepaald welke van de mogelijke overeenkomende samengevoegde records zullen worden gebruikt in de Update(een probleem dat MERGEvermijdt door een fout op te heffen als er een poging is om dezelfde rij meer dan eens bij te werken).


Antwoord 7, autoriteit 2%

Voor de goede orde (en anderen die zoeken zoals ik), je kunt het als volgt in MySQL doen:

UPDATE first_table, second_table
SET first_table.color = second_table.color
WHERE first_table.id = second_table.foreign_id

Antwoord 8, autoriteit 2%

alias gebruiken:

UPDATE t
   SET t.col1 = o.col1
  FROM table1 AS t
         INNER JOIN 
       table2 AS o 
         ON t.id = o.id

Antwoord 9

De eenvoudige manier om dit te doen is:

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

Antwoord 10

Dit kan een niche-reden zijn om een ​​update uit te voeren (bijvoorbeeld voornamelijk gebruikt in een procedure), of kan voor anderen duidelijk zijn, maar er moet ook worden vermeld dat u een update-select-statement kunt uitvoeren zonder join ( in het geval dat de tabellen waartussen u bijwerkt geen gemeenschappelijk veld hebben).

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

Antwoord 11

Hier is nog een handige syntaxis:

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);

Het controleert of het null is of niet door “WHERE EXIST” te gebruiken.


Antwoord 12

Ik voeg dit alleen toe zodat je een snelle manier kunt zien om het te schrijven, zodat je kunt controleren wat er wordt bijgewerkt voordat je de update uitvoert.

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 

Antwoord 13

Als u MySQLgebruikt in plaats van SQL Server, is de syntaxis:

UPDATE Table1
INNER JOIN Table2
ON Table1.id = Table2.id
SET Table1.col1 = Table2.col1,
    Table1.col2 = Table2.col2

Antwoord 14

UPDATE van SELECT met INNER JOIN in SQL Database

Omdat er te veel reacties zijn op dit bericht, waar de meeste stemmen op zijn, dacht ik dat ik mijn suggestie hier ook zou geven. Hoewel de vraag erg interessant is, heb ik het op veel forumsites gezien en een oplossing gemaakt met behulp van INNER JOINmet screenshots.

Eerst heb ik een tabel gemaakt met de naam schoololden enkele records met betrekking tot hun kolomnamen ingevoegd en uitgevoerd.

Vervolgens heb ik de opdracht SELECTuitgevoerd om de ingevoegde records te bekijken.

Vervolgens maakte ik een nieuwe tabel met de naam schoolnewen voerde ik op dezelfde manier bovenstaande acties uit.

Vervolgens, om de ingevoegde records erin te bekijken, voer ik het SELECT-commando uit.

Nu, hier wil ik enkele wijzigingen aanbrengen in de derde en vierde rij, om deze actie te voltooien, voer ik de opdracht UPDATEuit met INNER JOIN.

Om de wijzigingen te bekijken, voer ik het commando SELECTuit.

Je kunt zien hoe Derde en Vierde records van tabel schoololdgemakkelijk kunnen worden vervangen door tabel schoolnewdoor INNER JOIN met UPDATE-instructie te gebruiken.


Antwoord 15

En als je met zichzelf aan de tafel wilde zitten (wat niet vaak zal gebeuren):

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

Antwoord 16

Bijwerken via CTEis beter leesbaar dan de andere antwoorden hier:

;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

Antwoord 17

Het volgende voorbeeld gebruikt een afgeleide tabel, een SELECT-instructie na de FROM-component, om de oude en nieuwe waarden te retourneren voor verdere updates:

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

Antwoord 18

Als u SQL Server gebruikt, kunt u de ene tabel bijwerken vanuit de andere zonder een join op te geven en eenvoudig de twee koppelen vanuit de where-clausule. Dit maakt een veel eenvoudigere SQL-query:

UPDATE Table1
SET Table1.col1 = Table2.col1,
    Table1.col2 = Table2.col2
FROM
    Table2
WHERE
    Table1.id = Table2.id

Antwoord 19

Hier worden alle verschillende benaderingen geconsolideerd.

  1. Selecteer update
  2. Bijwerken met een algemene tabeluitdrukking
  3. Samenvoegen

De structuur van de voorbeeldtabel staat hieronder en wordt bijgewerkt van Product_BAK naar Producttabel.

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. Selecteer update

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

2. Update met een algemene tabeluitdrukking

   ; 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. Samenvoegen

   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;

In deze Merge-instructie kunnen we invoegen als we geen overeenkomend record in het doel vinden, maar in de bron bestaan ​​en de syntaxis vinden:

   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);

Antwoord 20

De andere manier is om een ​​afgeleide tabel te gebruiken:

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

Voorbeeldgegevens

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

Antwoord 21

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

Om er zeker van te zijn dat u bijwerkt wat u wilt, selecteert u eerst

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

Antwoord 22

Er is zelfs een kortere methodeen het kan voor u verrassend zijn:

Voorbeeldgegevensset:

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');

Code:

UPDATE #DEST
SET #DEST.[Desc] = #SOURCE.[Desc]
FROM #SOURCE
WHERE #DEST.[ID] = #SOURCE.[ID];

Antwoord 23

Gebruik:

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

BEIDE:

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')

OF:

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

Als de ID-kolomnaam in beide tabellen hetzelfde is, plaats dan gewoon de tabelnaam voor de tabel die moet worden bijgewerkt en gebruik een alias voor de geselecteerde tabel, d.w.z.:

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')

Antwoord 24

In het geaccepteerde antwoord, na de:

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

Ik zou toevoegen:

OUTPUT deleted.*, inserted.*

Wat ik meestal doe is alles in een roll-backed transactie zetten en de "OUTPUT"gebruiken: op deze manier zie ik alles wat er gaat gebeuren. Als ik tevreden ben met wat ik zie, verander ik de ROLLBACKin COMMIT.

Ik moet meestal documenteren wat ik heb gedaan, dus gebruik ik de optie "results to Text"wanneer ik de teruggedraaide query uitvoer en ik zowel het script als het resultaat van de OUTPUT opsla. (Dit is natuurlijk niet praktisch als ik te veel rijen heb gewijzigd)


Antwoord 25

UPDATE table AS a
INNER JOIN table2 AS b
ON a.col1 = b.col1
INNER JOIN ... AS ...
ON ... = ...
SET ...
WHERE ...

Antwoord 26

De onderstaande oplossing werkt voor een MySQL-database:

UPDATE table1 a , table2 b 
SET a.columname = 'some value' 
WHERE b.columnname IS NULL ;

Antwoord 27

De andere manier om te updaten vanuit een select statement:

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'

Antwoord 28

Optie 1: Inner Join gebruiken:

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

Optie 2: Co-gerelateerde subquery

UPDATE table 
SET Col1 = B.Col1, 
    Col2 = B.Col2 
FROM (
    SELECT ID, Col1, Col2 
    FROM other_table) B
WHERE 
    B.ID = table.ID

Antwoord 29

UPDATE table1
SET column1 = (SELECT expression1
               FROM table2
               WHERE conditions)
[WHERE conditions];

De syntaxis voor de UPDATE-instructie bij het bijwerken van een tabel met gegevens uit een andere tabel in SQL Server


Antwoord 30

Belangrijk om erop te wijzen dat, zoals anderen hebben gedaan, MySQLof MariaDBeen andere syntaxis gebruiken. Het ondersteunt ook een zeer handige USING-syntaxis (in tegenstelling tot T/SQL). Ook INNER JOIN is synoniem met JOIN. Daarom zou de query in de oorspronkelijke vraag het beste als volgt in MySQL kunnen worden geïmplementeerd:

UPDATE
    Some_Table AS Table_A
JOIN
    Other_Table AS Table_B USING(id)
SET
    Table_A.col1 = Table_B.col1,
    Table_A.col2 = Table_B.col2
WHERE
    Table_A.col3 = 'cool'

Ik heb de oplossing voor de gestelde vraag in de andere antwoorden niet gezien, vandaar mijn twee cent.
(getest op PHP 7.4.0 MariaDB 10.4.10)

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes