关于内部选择和连接的SQL建议

时间:2017-09-22 10:17:08

标签: sql sql-server

我和一位同事讨论过一段关于sql的问题。在一个项目中,我写了这样的东西:

update MyTable
set field1 = (select count(distinct blabla)
              from anotherTable t
              inner join againAnotherTable t2 on t2.fk = t1.pk
              where t2.fk = MyTable.fk)

在一些单元测试之后,字段" field1" MyTable的正确填充有效值。我的同事告诉我,我很幸运,因为我在内部查询(t2.fk = MyTable.fk)中的链接不一致,有时我可能会遇到一些错误并更新错误的行或更新整个表。相反,我应该在括号结束后加入一个连接

我错过了什么吗?我身边确实有一个巨大的错误吗?

3 个答案:

答案 0 :(得分:1)

您的查询对我来说很好。

请注意,它会更新整个表,因为where没有update子句(或其他过滤)。不匹配的行的值为0。我不知道这是不是你想要的。

当然,这完全取决于t2.fk = MyTable.fk是否是您真正想要的逻辑。我不知道"不一致"在这种情况下意味着。

我不知道如何更改数据会导致错误。您可能会得到意外的值。例如,如果您打算将NULL的{​​{1}}值匹配,则他们不会。如果没有匹配项,那么您将获得fk。可能不是正确的结果(基于您想要的逻辑),但查询会做一些合理的事情。

答案 1 :(得分:1)

如果你想以这种方式实际更新它,这个查询是可以的,但如果你想用连接更新字段,并包括正在更新的表,不要这样写。

您的同事正在努力确保您日后编写更安全的更新查询。他希望有一天,在子查询中你不会错过where t2.fk = MyTable.fk。这会错误地更新表格。

在那种情况下,写下如下所示,

update a set a.field1 = b.value 
  FROM MyTable a INNER JOIN anotherTable b ON a.condition1 = b.condition2
     INNER JOIN yetAnotherTable c ON a.condition1 = c.condition2
  

因此,您应该将更新查询更改为以下内容

update a
set field1 = count(distinct blabla) 
FROM anotherTable b INNER JOIN againAnotherTable t2 on t2.fk = t1.pk 
INNER JOIN MyTable a ON t2.fk = MyTable.fk

答案 2 :(得分:0)

declare @field1 datatype 

set @field1 = (select count(distinct blabla)
          from anotherTable t
          inner join againAnotherTable t2 on t2.fk = t1.pk
          where t2.fk = MyTable.fk)

update table set column=@field1 where id=''