3

在 T-Sql 中编码自三个多月以来,我第一次看到在某些代码CROSS JOIN中的UPDATE语句中使用 a 并且我无法弄清楚这种构造的用例。

有人知道吗?

编辑:这是一个我还不能很好理解的示例代码。

UPDATE a
SET a.COL1 = b.COL1
FROM Table1 AS a
CROSS JOIN Table2 AS b

代码中还有其他更新提供了WHERE如下子句:

UPDATE a
SET a.COL1 = b.COL1
FROM Table1 AS a
CROSS JOIN Table2 AS b
WHERE condition_on_columns_from_a_and_from_b

关键是对于 Table1 的每一行,带有过滤的交叉连接上的选择返回多行。

我对这种行为的理解有点困惑。

PS:表 Table1 占用超过 5 GB 的空间..

4

4 回答 4

2

我没有充分的理由可以想象这样做。查询要么写错了,要么只是为了减慢系统速度或使目标表的数据无效(或者只是为了看看它做了什么)。

它可能会将 Table1 中每一行的 COL1 设置为与 Table2 的 COL1 相同的单个随机值(尽管可能是第一个或最后一个这样的值)。但是这样做会非常低效(除非 SQL Server 更高版本中的优化器已经优化了这种无用的情况,否则我自己已经很多年没有测试过了)。

于 2013-04-17T16:45:45.057 回答
2

交叉连接生成两个表的笛卡尔积。这意味着它将表 A 的每一行与表 B 的每一行组合在一起。当表 A 有 n 行而表 B 有 m 行时,结果集有 n*m 行。

于 2013-04-17T13:00:17.003 回答
0

要了解用例,您需要查看数据。如果我是肯定的,我可以很容易地看到使用第一次更新 tableb 将始终并且只包含一条记录。对于一条记录没有要连接到表 A 上的字段的情况尤其如此。在这种情况下,您将使用表 b 中该字段的值更新表 a 中的所有字段。通常这种更新所有记录的事情只会用于重置值。

要查看将更新的内容,请执行以下操作:

UPDATE a
SET a.COL1 = b.COL1
--select a.COL1,b.COL1, *
FROM Table1 AS a
CROSS JOIN Table2 AS b
WHERE condition_on_columns_from_a_and_from_b

现在您可以只运行 select 部分来查看 a.col1 将被替换为什么值,并查看表中的其他字段以查看连接是否正确以及 where clasue 是否正确。这将帮助您了解 corss join 的作用。然后,您可以暂时将交叉连接替换为左连接和内连接,以了解它与其他类型的连接不同的行为。玩一会儿选择,直到你真正理解发生了什么。我从来没有在评论中没有选择的情况下编写更新,因此我可以确保在将代码移动到 prod 之前我正在更新我认为应该是的内容。如果您像我一样编写复杂的更新,这可能涉及十或十五个连接和几个 where 条件,则尤其如此。

于 2013-04-17T17:56:53.803 回答
0

好的,使用此查询:

UPDATE a
SET COL1 = b.COL1
FROM Table1 AS a
CROSS JOIN Table2 AS b
WHERE condition_on_columns_from_a_and_from_b

如果我们取由a CROSS JOIN b(在考虑FROM子句之前)形成的集合,那么我们有一个笛卡尔积,其中来自a的每一行都与来自的每一行配对b

如果我们现在考虑该WHERE子句——除非WHERE子句足以保证其中的每一行a只表示一次,否则我们将得到一个不确定的结果。也就是说,如果集合中有两行都来自同一行a(但来自不同的行b),则无法确定这两行中的哪一行将用于计算SET a.COL1 = b.COL1分配.

如果我们有以下情况,我认为它甚至不能保证:

UPDATE a
SET COL1 = b.COL1, COL2 = b.COL2
FROM --As before

同一行将用于这两个任务b

以上所有对于使用 T-SQL子句扩展的任何 语句都是正确的- 除非您小心地约束您的连接条件,否则同一行的多个分配是可能的。但是,a just 似乎使它更有可能发生。如果发生这种情况,SQL Server 不会发出任何诊断消息。UPDATEFROMCROSS JOIN

于 2013-04-18T06:16:35.513 回答