【问题标题】:SQL Server query weird behaviourSQL Server 查询奇怪的行为
【发布时间】:2014-03-15 07:41:57
【问题描述】:

我在 SQL Server 中的查询遇到了一个奇怪的行为

我有两个表 PrepaidTransactionsBillingData,我正在执行以下查询

Select * 
from PrepaidTransactions 
where customer_Id in
                  (Select customer_Id 
                   from BillingData 
                   where CommunityId = 10004)

customer_Id 不属于表BillingData。查询正在执行并返回 PrepaidTransactions 表中的所有记录,而不是显示错误

但是当我运行以下查询时

Select customer_Id 
from BillingData 
where CommunityId = 10004

显示错误

列名“customer_Id”无效。

谁能告诉我为什么第一个查询没有显示任何错误?

【问题讨论】:

  • 第一个查询运行是因为customer_Id 明确解析为PrepaidTransactions.customer_Id
  • 我很确定结果集不是您所期望的
  • @MoslemBenDhaou ,是的,结果集不是我所期望的。
  • @MartinSmith,是的,它可能是重复的,但是在发布这个问题之前,我检查并找不到它。

标签: sql sql-server execution query-expressions


【解决方案1】:

我认为这两篇文章回答了你的问题。

https://connect.microsoft.com/SQLServer/feedback/details/542289/subquery-with-error-does-not-cause-outer-select-to-fail

http://support.microsoft.com/kb/298674

这是预期行为,因为您的列名未绑定到表。因此,如果它可以在外部表中解决(在您的查询的情况下,它可以),那么子查询不会失败。如果您指定表 BillingData.customer_Id,您将失败。文章说要遵循这种做法以避免歧义。

【讨论】:

  • 第二个链接中的 kb 文章指出,In the case of an unqualified column name, the query optimizer assumes that the query is a correlated subquery,现在我明白了确切的原因以及为什么应该在子查询中使用完全限定的列名。
【解决方案2】:

哇!我认为在您的第一种情况下,customer_Id 是从外部查询中提取的。你可以通过做一个表前缀来测试:

Select * from PrepaidTransactions where customer_Id in
(Select PrepaidTransactions.customer_Id from BillingData where CommunityId = 10004)

得到相同的结果,但是

Select * from PrepaidTransactions where customer_Id in
(Select BillingData.customer_Id from BillingData where CommunityId = 10004)

我敢打赌是错误?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    • 1970-01-01
    相关资源
    最近更新 更多