混合加入时更新的范围规则是什么?

发布于 2025-01-25 14:42:37 字数 487 浏览 5 评论 0原文

每当我阅读如何使用加入更新表时,别名的用法总是会稍微抛弃我。例如,从

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

代码> ud 第1行上的表。我不清楚的是为什么ud需要在第3和4行上被别名。这不是孤立的事件。例如,同一页面上的另一个答案是

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

在许多地方使用别名u

这给了我我的问题:尝试使用加入 更新时,您所做的/不需要别名的规则到底是什么?直接引用任何相关文档将不胜感激,但不需要。

Whenever I read how to use a JOIN to UPDATE a table, the usage of aliases always throws me off just slightly. For example, take this code from here

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

It's clear to me that assid comes from the ud table on the line 1. What isn't clear to me is why ud needed to be aliased on lines 3 and 4. This isn't an isolated incident. For example, another answer on that same page is

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

which uses the alias u in a great many places.

This gives me my question: What exactly are the rules for what you do/don't need to alias when trying to use a JOIN to UPDATE? Directly quoting from any relevant docs would be appreciated, but not required.

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

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

发布评论

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

评论(3

硬不硬你别怂 2025-02-01 14:42:37

documentation

来自< table_source>

... snip ...

如果要更新的对象与子句中的对象相同,并且从中的对象中只有一个引用从子句中的对象,则对象别名可能或可能未指定。如果要更新的对象在子句中出现多次以上,一个,一个,仅一个,则对对象的引用不得指定表别名。来自条款中中对象的所有其他引用必须包括一个对象别名。


您没有 来指定任何表的别名。如果您不这样做,则表显然只能指定一次。

但是,如果您确实给出了一个别名,则取决于:如果表格在查询中存在一次,则可以有或没有别名。否则您必须使用别名。

说实话, as @aaronbertrand说始终在每个表上使用一个别名,并在更新别名集 part中指定该别名。

同样,您应始终在连接或表达式中的每个列参考中使用表别名。这与您在任何选择中都应该做的相同。

但是,我不要认为有必要在分配给的左侧列上使用它,因为这些只能来自一个表/视图/别名:关键字update,因此添加表别名只是词。
在SQL方言(例如MySQL)中,确实允许这样做,然后您也应该在左侧指定表格。

column_name

是包含要更改的数据的列。 column_name必须存在于table_or view_name中。

因此,推荐的陈述看起来像这样:

UPDATE u     -- use the alias mentioned below
SET
  assid = s.assid    -- lh-side doesn't need alias, right-side does
FROM ud u    -- alias all tables
JOIN sale s ON u.id = s.id    -- add table aliases to all columns in joins

The documentation calls this out specifically:

FROM <table_source>

... snip ...

If the object being updated is the same as the object in the FROM clause and there is only one reference to the object in the FROM clause, an object alias may or may not be specified. If the object being updated appears more than one time in the FROM clause, one, and only one, reference to the object must not specify a table alias. All other references to the object in the FROM clause must include an object alias.

You do not have to specify an alias for any table. If you do not then the table can obviously only be specified once.

But if you do give an alias then it depends: if the table exists in the query once then either with or without an alias is OK. Otherwise you must use the alias.

To be honest, as @AaronBertrand says, do yourself and everyone a favour and always use an alias on each table, and specify that alias in the UPDATE alias SET part.

Equally you should always use table aliases for each column reference in the joins or expressions. This is the same as you should do in any SELECT.

However, I don't think it's necessary to use it on the left-hand-side columns being assigned to, as these can only ever be from a single table/view/alias: the one directly after the keyword UPDATE, so adding table aliases is just verbiage.
In SQL dialects such as MySQL which do allow this then you should specify the table alias even on the left-hand-side.

column_name

Is a column that contains the data to be changed. column_name must exist in table_or view_name.

So a recommended statement would look like this:

UPDATE u     -- use the alias mentioned below
SET
  assid = s.assid    -- lh-side doesn't need alias, right-side does
FROM ud u    -- alias all tables
JOIN sale s ON u.id = s.id    -- add table aliases to all columns in joins
季末如歌 2025-02-01 14:42:37

如果您使用CTE而不是更新,则这些都不是神秘的。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

  select u.id, u.assid, s.assid new_assid 
  FROM ud u
  JOIN sale s ON u.id=s.id

请注意, 检查并验证数据,然后将其包装在CTE中并进行更新

with q as
(
  select u.id, u.assid, s.assid new_assid 
  FROM ud u
  JOIN sale s ON u.id=s.id
)
update q set assid = new_assid

Note that none of this is mysterious if you use a CTE instead of UPDATE ... FROM, eg start with a SELECT that returns the rows you want to update

  select u.id, u.assid, s.assid new_assid 
  FROM ud u
  JOIN sale s ON u.id=s.id

. Examine and validate the data, then wrap it in a CTE and UPDATE it

with q as
(
  select u.id, u.assid, s.assid new_assid 
  FROM ud u
  JOIN sale s ON u.id=s.id
)
update q set assid = new_assid
卖梦商人 2025-02-01 14:42:37

从技术上讲,您不需要 在列引用上使用别名前缀:

  • set set的左侧,因为从逻辑上讲,该列不可能出现从任何其他表中,
  • 没有列名称冲突需要歧义(并且您确定您永远不会在任何涉及的表中添加列可能会成为冲突的列表)

如果 关于您何时可以摆脱不是前缀的任何“规则”,并且只始终引用列属于的别名。为什么不总是清楚和明确呢?

如果您正在寻找“官方”规则,我认为您会失去运气。关于这一点找不到,尽管第一个示例有一个示例,这是有点iMho(并且不使用别名):

UPDATE dbo.Table2   
SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB  
FROM dbo.Table2   
    INNER JOIN dbo.Table1   
    ON (dbo.Table2.ColA = dbo.Table1.ColA);  

在此站点上,许多长期存在的规范示例在所有列参考上都完全明确,例如

Technically, you don't need to use an alias prefix on a column reference:

  • in the left-hand side of SET since, logically, that column can't possibly come from any other table
  • if there are no column name conflicts that need disambiguation (and you know for sure you will never add columns to any of the involved tables that could become a conflict)

IMHO you shouldn't worry about any "rules" about when you can get away with not prefixing, and just always reference the alias a column belongs to. Why not just be clear and explicit always?

If you're looking for "official" rules, I think you'll be out of luck. Nothing about this could be found in this doc, though the first example has this, which is a little overboard IMHO (and doesn't use aliases):

UPDATE dbo.Table2   
SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB  
FROM dbo.Table2   
    INNER JOIN dbo.Table1   
    ON (dbo.Table2.ColA = dbo.Table1.ColA);  

On this site, many long-standing canonical examples are fully explicit on all column references, e.g. this one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文