如何在 SQL Server 中使用 JOIN 执行 UPDATE 语句?

发布于 2024-08-02 00:09:18 字数 342 浏览 7 评论 0 原文

我需要使用其“父”表中的数据更新 SQL Server 中的此表,如下所示:

表:sale

id (int)
udid (int)
assid (int)

表:ud

id  (int)
assid  (int)

sale.assid 包含更新 ud.assid 的正确值。

什么查询会执行此操作? 我正在考虑加入,但我不确定是否可行。

I need to update this table in SQL Server with data from its 'parent' table, see below:

Table: sale

id (int)
udid (int)
assid (int)

Table: ud

id  (int)
assid  (int)

sale.assid contains the correct value to update ud.assid.

What query will do this? I'm thinking of a join but I'm not sure if it's possible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

终陌 2024-08-09 00:09:18

语法严格取决于您使用的 SQL DBMS。 以下是在 ANSI/ISO(也适用于任何 SQL DBMS)、MySQL、SQL Server 和 Oracle 中执行此操作的一些方法。 请注意,我建议的 ANSI/ISO 方法通常比其他两种方法慢得多,但如果您使用的是 MySQL、SQL Server 或 Oracle 之外的 SQL DBMS,那么它可能是唯一的方法(例如如果您的 SQL DBMS 不支持 MERGE):

ANSI/ISO:

update ud 
     set assid = (
          select sale.assid 
          from sale 
          where sale.udid = ud.id
     )
 where exists (
      select * 
      from sale 
      where sale.udid = ud.id
 );

MySQL:

update ud u
inner join sale s on
    u.id = s.udid
set u.assid = s.assid

SQL Server:

update u
set u.assid = s.assid
from ud u
    inner join sale s on
        u.id = s.udid

PostgreSQL:

update ud
  set assid = s.assid
from sale s 
where ud.id = s.udid;

请注意,目标表不得在 FROM 子句中重复Postgres。 主要问题:如何在 PostgreSQL 中进行更新+连接?

Oracle:

update
    (select
        u.assid as new_assid,
        s.assid as old_assid
    from ud u
        inner join sale s on
            u.id = s.udid) up
set up.new_assid = up.old_assid

SQLite:

update ud 
     set assid = (
          select sale.assid 
          from sale 
          where sale.udid = ud.id
     )
 where RowID in (
      select RowID 
      from ud 
      where sale.udid = ud.id
 );

SQLite 3.33 添加了对类似于 PostgreSQL 语法的 UPDATE + FROM 语法的支持:

update ud
  set assid = s.assid
from sale s 
where ud.id = s.udid;

主要问题:在 SQLite 中使用 Join 进行更新

Syntax strictly depends on which SQL DBMS you're using. Here are some ways to do it in ANSI/ISO (aka should work on any SQL DBMS), MySQL, SQL Server, and Oracle. Be advised that my suggested ANSI/ISO method will typically be much slower than the other two methods, but if you're using a SQL DBMS other than MySQL, SQL Server, or Oracle, then it may be the only way to go (e.g. if your SQL DBMS doesn't support MERGE):

ANSI/ISO:

update ud 
     set assid = (
          select sale.assid 
          from sale 
          where sale.udid = ud.id
     )
 where exists (
      select * 
      from sale 
      where sale.udid = ud.id
 );

MySQL:

update ud u
inner join sale s on
    u.id = s.udid
set u.assid = s.assid

SQL Server:

update u
set u.assid = s.assid
from ud u
    inner join sale s on
        u.id = s.udid

PostgreSQL:

update ud
  set assid = s.assid
from sale s 
where ud.id = s.udid;

Note that the target table must not be repeated in the FROM clause for Postgres. Main question: How to do an update + join in PostgreSQL?

Oracle:

update
    (select
        u.assid as new_assid,
        s.assid as old_assid
    from ud u
        inner join sale s on
            u.id = s.udid) up
set up.new_assid = up.old_assid

SQLite:

update ud 
     set assid = (
          select sale.assid 
          from sale 
          where sale.udid = ud.id
     )
 where RowID in (
      select RowID 
      from ud 
      where sale.udid = ud.id
 );

SQLite 3.33 added support for an UPDATE + FROM syntax analogous to the PostgreSQL one:

update ud
  set assid = s.assid
from sale s 
where ud.id = s.udid;

Main question: Update with Join in SQLite

倾城泪 2024-08-09 00:09:18

这应该适用于 SQL Server:

update ud 
set assid = sale.assid
from sale
where sale.udid = id

This should work in SQL Server:

update ud 
set assid = sale.assid
from sale
where sale.udid = id
书信已泛黄 2024-08-09 00:09:18

PostgreSQL

UPDATE table1
SET    COLUMN = value
FROM   table2,
       table3
WHERE  table1.column_id = table2.id
       AND table1.column_id = table3.id
       AND table1.COLUMN = value
       AND table2.COLUMN = value
       AND table3.COLUMN = value

PostgreSQL

UPDATE table1
SET    COLUMN = value
FROM   table2,
       table3
WHERE  table1.column_id = table2.id
       AND table1.column_id = table3.id
       AND table1.COLUMN = value
       AND table2.COLUMN = value
       AND table3.COLUMN = value
永不分离 2024-08-09 00:09:18

标准的 SQL 方法是

UPDATE ud
SET assid = (SELECT assid FROM sale s WHERE ud.id=s.id)

在 SQL Server 上,您可以使用联接

UPDATE ud
SET assid = s.assid
FROM ud u
JOIN sale s ON u.id=s.id

A standard SQL approach would be

UPDATE ud
SET assid = (SELECT assid FROM sale s WHERE ud.id=s.id)

On SQL Server you can use a join

UPDATE ud
SET assid = s.assid
FROM ud u
JOIN sale s ON u.id=s.id
漆黑的白昼 2024-08-09 00:09:18

PostgreSQL

CREATE TABLE ud (id integer, assid integer);
CREATE TABLE sales (id integer, udid integer, assid integer);

UPDATE ud
SET assid = sales.assid
FROM sales
WHERE sales.id = ud.id;

PostgreSQL:

CREATE TABLE ud (id integer, assid integer);
CREATE TABLE sales (id integer, udid integer, assid integer);

UPDATE ud
SET assid = sales.assid
FROM sales
WHERE sales.id = ud.id;
傲世九天 2024-08-09 00:09:18

使用JOIN连接多个表简化了更新查询。

   UPDATE
        first_table ft
        JOIN second_table st ON st.some_id = ft.some_id
        JOIN third_table tt  ON tt.some_id = st.some_id
        .....
    SET
        ft.some_column = some_value
    WHERE ft.some_column = 123456 AND st.some_column = 123456

注意 -first_table、second_table、third_table 和 some_column(如 123456)是演示表名称、列名称和 ID。 将它们替换为有效名称。

Simplified update query using JOIN-ing multiple tables.

   UPDATE
        first_table ft
        JOIN second_table st ON st.some_id = ft.some_id
        JOIN third_table tt  ON tt.some_id = st.some_id
        .....
    SET
        ft.some_column = some_value
    WHERE ft.some_column = 123456 AND st.some_column = 123456

Note - first_table, second_table, third_table and some_column like 123456 are demo table names, column names and ids. Replace them with the valid names.

〆凄凉。 2024-08-09 00:09:18

SQL 并不真正可移植的另一个例子。

对于 MySQL 来说是:

update ud, sale
set ud.assid = sale.assid
where sale.udid = ud.id;

有关更多信息,请阅读多个表更新:
http://dev.mysql.com/doc/refman/5.0/en /update.html

UPDATE [LOW_PRIORITY] [IGNORE] table_references
    SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
    [WHERE where_condition]

Another example why SQL isn't really portable.

For MySQL it would be:

update ud, sale
set ud.assid = sale.assid
where sale.udid = ud.id;

For more info read multiple table update:
http://dev.mysql.com/doc/refman/5.0/en/update.html

UPDATE [LOW_PRIORITY] [IGNORE] table_references
    SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
    [WHERE where_condition]
很酷又爱笑 2024-08-09 00:09:18

Teradata 的 Aster 提供了另一种实现这一目标的有趣方法:

MERGE INTO ud --what table should be updated
USING sale -- from what table/relation update info should be taken
ON ud.id = sale.udid --join condition
WHEN MATCHED THEN 
    UPDATE SET ud.assid = sale.assid; -- how to update

Teradata's Aster offers another interesting way how to achieve the goal:

MERGE INTO ud --what table should be updated
USING sale -- from what table/relation update info should be taken
ON ud.id = sale.udid --join condition
WHEN MATCHED THEN 
    UPDATE SET ud.assid = sale.assid; -- how to update
梦巷 2024-08-09 00:09:18

我认为顶帖中的 SQL Server 适合 Sybase 因为它们都是 T -SQL,但不幸的是没有。

对于 Sybase,我发现更新需要在表本身上,而不是别名上:

update ud
set u.assid = s.assid
from ud u
    inner join sale s on
        u.id = s.udid

I was thinking the SQL Server one in the top post would work for Sybase since they are both T-SQL, but unfortunately not.

For Sybase, I found the update needs to be on the table itself, not the alias:

update ud
set u.assid = s.assid
from ud u
    inner join sale s on
        u.id = s.udid
南巷近海 2024-08-09 00:09:18

MySQL

如果忘记 where 子句并将所有条件放在 ON 表达式中,您将获得最佳性能。

我认为这是因为查询首先必须连接表,然后在其上运行 where 子句,因此如果您可以减少连接所需的内容,那么这就是获取结果/执行更新的快速方法。

示例

场景

您有一个用户表。 他们可以使用用户名电子邮件电话号码登录。 这些帐户可以是活动的 (1) 或非活动的 (0)。 该表有 50000 行

然后您就可以一次性禁用一张用户表(列入黑名单),因为您发现他们都做了坏事。

运行一个脚本来检查 blacklist_users 表中的用户并在 users 表中禁用它们。

然而,这个blacklist_users表只有一列,其中用户名电子邮件帐号全部混合在一起。

blacklist_users 表还有一个“has_run”指示器,运行时需要将其设置为 1 (true),以便在以后的查询中可以跳过它。

因此,如果这里有一个 WHERE 子句,在内部,结果将返回到联接中,然后针对该数据集查询 WHERE 子句。 相反,我们可以将所有 where 子句条件移至连接中,并在内部完全删除第二个查询。

因此,这是避免不必要地查找 users 表的最佳查询...

查询

UPDATE users User
    INNER JOIN
        blacklist_users BlacklistUser
        ON
        (
            User.username = BlacklistUser.account_ref
            OR
            User.email = BlacklistedUser.account_ref
            OR
            User.phone_number = BlacklistUser.account_ref
            AND
            User.is_active = 1
            AND
            BlacklistUser.has_run = 0
        )
    SET
        User.is_active = 0,
        BlacklistUser.has_run = 1;

推理

如果我们必须仅连接 OR 条件,则基本上需要检查每一行 4 次(1对于电子邮件,1对于电话号码,1对于用户名,1对于is_active)来查看是否应该加入,并可能返回更多行。 然而,通过给它更多的条件,它可以“跳过”我们不更新的每一行。

额外的好处

是它更具可读性。 所有条件都位于一个位置,而要更新的行位于另一位置。

我希望这一切都是有意义的。

MySQL

You'll get the best performance if you forget the where clause and place all conditions in the ON expression.

I think this is because the query first has to join the tables and then runs the where clause on that, so if you can reduce what is required to join then that's the fasted way to get the results/do the update.

Example

Scenario

You have a table of users. They can log in using their username or email or phone_number. These accounts can be active (1) or inactive (0). This table has 50000 rows

You then have a table of users to disable (blacklist) at one go because you find out they've all done something bad.

A script runs that checks for users in the blacklist_users table and disables them in the users table.

This blacklist_users table however, only has one column with usernames, emails and account numbers all mixed together.

The blacklist_users table also has a "has_run" indicator which needs to be set to 1 (true) when it has been run so it can be skipped in future queries.

So if you have a WHERE clause here, internally, the results are getting brought back in the join and then the WHERE clause is being queried against that dataset. Instead, we can move all the where clause conditions into the join, and internally, remove the second query completely.

Therefore, this is the most optimal query to avoid needless lookups of the users table...

Query

UPDATE users User
    INNER JOIN
        blacklist_users BlacklistUser
        ON
        (
            User.username = BlacklistUser.account_ref
            OR
            User.email = BlacklistedUser.account_ref
            OR
            User.phone_number = BlacklistUser.account_ref
            AND
            User.is_active = 1
            AND
            BlacklistUser.has_run = 0
        )
    SET
        User.is_active = 0,
        BlacklistUser.has_run = 1;

Reasoning

If we had to join on just the OR conditions it would essentially need to check each row 4 times (1 for email, 1 for phone_number, 1 for username, 1 for is_active) to see if it should join, and potentially return a lot more rows. However, by giving it more conditions it can "skip" every row we're not updating.

Bonus

It's more readable. All the conditions are in one place and the rows to update are in another place.

I hope all that makes sense.

宫墨修音 2024-08-09 00:09:18

最简单的方法是使用通用表表达式 (CTE) SQL Server 2005 中引入:

with cte as
(select u.assid col1 ,s.assid col2 from ud u inner join sale s on u.id = s.udid)
update cte set col1=col2

The simplest way is to use the Common Table Expression (CTE) introduced in SQL Server 2005:

with cte as
(select u.assid col1 ,s.assid col2 from ud u inner join sale s on u.id = s.udid)
update cte set col1=col2
错々过的事 2024-08-09 00:09:18

以下带有 FROM 关键字的语句用于通过联接更新多行:

UPDATE users
set users.DivisionId=divisions.DivisionId
from divisions join users on divisions.Name=users.Division

The following statement with the FROM keyword is used to update multiple rows with a join:

UPDATE users
set users.DivisionId=divisions.DivisionId
from divisions join users on divisions.Name=users.Division
開玄 2024-08-09 00:09:18

Microsoft Access 中:

UPDATE ud
INNER JOIN sale ON ud.id = sale.udid
SET ud.assid = sale.assid;

And in Microsoft Access:

UPDATE ud
INNER JOIN sale ON ud.id = sale.udid
SET ud.assid = sale.assid;
策马西风 2024-08-09 00:09:18

试试这个。 我认为这对你有用。

update ud

set ud.assid = sale.assid

from ud

Inner join sale on ud.id = sale.udid

where sale.udid is not null

Try this one. I think this will work for you.

update ud

set ud.assid = sale.assid

from ud

Inner join sale on ud.id = sale.udid

where sale.udid is not null
找回味觉 2024-08-09 00:09:18
UPDATE tblAppraisalBasicData
SET tblAppraisalBasicData.ISCbo=1
FROM tblAppraisalBasicData SI INNER JOIN  aaa_test RAN ON SI.EmpID = RAN.ID
UPDATE tblAppraisalBasicData
SET tblAppraisalBasicData.ISCbo=1
FROM tblAppraisalBasicData SI INNER JOIN  aaa_test RAN ON SI.EmpID = RAN.ID
爱情眠于流年 2024-08-09 00:09:18

对于 SQLite,使用 RowID 属性进行更新:

update Table set column = 'NewValue'
where RowID = 
(select t1.RowID from Table t1
join Table2 t2 on t1.JoinField = t2.JoinField
where t2.SelectValue = 'FooMyBarPlease');

For SQLite use the RowID property to make the update:

update Table set column = 'NewValue'
where RowID = 
(select t1.RowID from Table t1
join Table2 t2 on t1.JoinField = t2.JoinField
where t2.SelectValue = 'FooMyBarPlease');
假情假意假温柔 2024-08-09 00:09:18

对于使用 PrestaShop 用户wiki/MySQL" rel="nofollow noreferrer">MySQL 5.7:

UPDATE
    ps_stock_available sa
    INNER JOIN ps_shop s
        ON sa.id_shop = s.id_shop AND s.id_shop = 1
    INNER JOIN ps_order_detail od
        ON sa.id_product = od.product_id AND od.id_order = 22417
SET
    sa.physical_quantity = sa.quantity + sa.reserved_quantity

这是一个示例,但要点正如 Eric 在 如何在 SQL Server 中使用 JOIN 执行 UPDATE 语句?

您需要在首先添加一条UPDATE语句,其中包含要连接的所有表的完整地址,然后然后添加SET< /代码> 声明。

For PrestaShop users who use MySQL 5.7:

UPDATE
    ps_stock_available sa
    INNER JOIN ps_shop s
        ON sa.id_shop = s.id_shop AND s.id_shop = 1
    INNER JOIN ps_order_detail od
        ON sa.id_product = od.product_id AND od.id_order = 22417
SET
    sa.physical_quantity = sa.quantity + sa.reserved_quantity

This was an example, but the point is as Eric said in How can I do an UPDATE statement with JOIN in SQL Server?.

You need to add an UPDATE statement at first with the full address of all tables to join with, and then add the SET statement.

梓梦 2024-08-09 00:09:18

要在 SQL Server 中使用 JOIN 执行 UPDATE 语句,可以将 JOIN 语法与 UPDATE 语句结合使用。 下面是一个示例查询,应根据 sale 表中的相应值更新 ud 表:

UPDATE ud
SET ud.assid = sale.assid
FROM ud
JOIN sale ON ud.id = sale.udid;

在此查询中,正在更新 ud 表,并根据匹配的 id 和 udid 列在 ud 和 sale 表之间执行 JOIN , 分别。 SET 子句指定要更新的列 ud.assid,并为其分配 sale.assid 列中的值。

dbForge Studio 的 SQL 编辑器使您能够执行查询并熟练管理数据库。

To perform an UPDATE statement with a JOIN in SQL Server, you can use the JOIN syntax in combination with the UPDATE statement. Here's an example query that should update the ud table based on the corresponding values from the sale table:

UPDATE ud
SET ud.assid = sale.assid
FROM ud
JOIN sale ON ud.id = sale.udid;

In this query, the ud table is being updated, and the JOIN is performed between the ud and sale tables based on the matching id and udid columns, respectively. The SET clause specifies the column to be updated, ud.assid, and assigns it the value from the sale.assid column.

dbForge Studio'se SQL editor empowers you to execute your queries and proficiently manage your databases.

拥抱我好吗 2024-08-09 00:09:18

我遇到了类似的情况,我需要从 postgresql 中的 Corporate_subscriptions 中获取并更新 user_id 。 以下查询适用于我的情况:

update orders set user_id=cs_user_id from (select o.id, o.user_id as order_user_id, cs.id as cs_id, cs.user_id as cs_user_id from orders o right join corporate_subscriptions cs on cs.id=o.corporate_subscription_id where corporate_subscription_id is not null) o where orders.id=o.id and orders.source='Subscription';

I had a similar situation where I needed to pick up and update user_id in orders from corporate_subscriptions in postgresql. The following query worked in my case:

update orders set user_id=cs_user_id from (select o.id, o.user_id as order_user_id, cs.id as cs_id, cs.user_id as cs_user_id from orders o right join corporate_subscriptions cs on cs.id=o.corporate_subscription_id where corporate_subscription_id is not null) o where orders.id=o.id and orders.source='Subscription';
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文