【问题标题】:Using a join in a merge statement在合并语句中使用连接
【发布时间】:2012-10-05 21:19:42
【问题描述】:

问题

表 1:

| KeyColumn | DataColumn1 | DataColumn2|  
   01         0.1          0.2
   02         0.13         0.41

表 2:

| anotherKey | DataColumn1 | DataColumn2|      
   A1          .15          1.2
   A2          .25          23.1

表 3:

|KeyColumn| anotherKey |       
  01        A1
  02        A1

给定一个键(A1 或 A2),我需要用表 2 中的相应值更新表 1 中的 DataColumn1 和 DataColumn2 列。

所以 table1 可以更新 x 行,如上数据所示。如果我想更新 A1,01 和 02 行都应该更新

(因此对于键 01 和 02,对于 datacolumn1,table1 中的值将是 0.15,对于 datacolumn2 的值将是 1.2)

到目前为止我所做的尝试:

MERGE table1
USING (SELECT *
       FROM table2
       LEFT OUTER JOIN table3
           on table2.anotherKey = table3.anotherKey
       WHERE table2.anotherKey = 'A1') tmpTable
ON 
   table1.keyColumn = tmpTable.keyColumn
WHEN MATCHED THEN
       UPDATE
       SET table1.DataColumn1 = tmpTable.DataColumn1
            ,table1.DataColumn2 = tmpTable.DataColumn2;

问题:

  1. 这是否允许?在using语句中使用select?我在第 1 行遇到语法错误
  2. 有没有更好的方法来解决这个问题?我是否让这变得比它必须的更复杂?
  3. 我做错了什么?

和错误:

消息 102,级别 15,状态 1,行 1 'a' 附近的语法不正确。 消息 102,第 15 级,状态 1,第 12 行 'd' 附近的语法不正确。

【问题讨论】:

  • 为什么要使用合并?看起来这可以通过更新来完成。
  • 我不知道,我在 SO 上阅读了一篇与此内容相同的帖子(没有外部连接),它说合并更适合。如果您能提供一个示例,说明如何仅通过更新来实现这一目标,我将永远感激不尽。
  • 如果没有匹配,我需要插入它。我还没有在查询中走那么远,因为我只是想让第一部分工作。这也是我选择合并的原因之一。我还在走错方向吗?
  • 好的,这是使用合并的好理由。
  • 如果缺少行,您似乎想同时向 table2table3 添加行。使用一个合并语句是不可能的。目标表基本上只能有一个。

标签: sql tsql merge


【解决方案1】:

你的查询会报错

Msg 8156, Level 16, State 1, Line 59 “AnotherKey”列是 为 'tmpTable' 指定了多次。

这是因为您在 using 子句中使用了*,而AnotherKeytable2table3 的一部分。
指定您需要的列。由于您在 onclause 中使用了 keycolumn,因此在那里进行外部连接也没有用处。

MERGE table1
USING (SELECT table3.keycolumn,
              table2.DataColumn1,
              table2.DataColumn2
       FROM table2
       INNER JOIN table3
           ON table2.anotherKey = table3.anotherKey
       WHERE table2.anotherKey = 'A1') tmpTable
ON 
   table1.keyColumn = tmpTable.keyColumn
WHEN MATCHED THEN
       UPDATE
       SET table1.DataColumn1 = tmpTable.DataColumn1
            ,table1.DataColumn2 = tmpTable.DataColumn2;

更新

发布实际错误总是有帮助的。

消息 102,级别 15,状态 1,第 1 行 'a' 附近的语法不正确。消息 102, 第 15 级,状态 1,第 12 行 'd' 附近的语法不正确。

看起来您使用的是 SQL Server 2005。可以从 SQL Server 2008 进行合并。

您可以使用select @@version 检查您的 SQL Server 版本。

【讨论】:

  • 在我的实际查询中,我没有在 using 子句中使用 *。我会发布实际的查询,因为它看起来和你做的一样
  • 是的,就是这样。我以为我们在 2008 年:/。谢谢!
  • 我有同样的问题..,但我加入和合并的条件涉及同一列。现在如何解决呢?
猜你喜欢
  • 1970-01-01
  • 2020-03-11
  • 1970-01-01
  • 1970-01-01
  • 2015-04-09
  • 1970-01-01
  • 1970-01-01
  • 2020-01-18
  • 2013-08-19
相关资源
最近更新 更多