今天我们发现了SQL Server 2012 SP1的一些奇怪行为。我们知道如何重现问题,但我们不确定是什么导致了这个问题。这是一个非常概括的例子:
假设您有一个数据库test,它有一个表table1,包含以下数据:
column1
-
1
2
3
4
您运行以下查询:
USE [test]
SELECT [column1]
FROM [test].[dbo].[table1]
WHERE [column1] IN
(SELECT TOP 5 [column1]
FROM [table1])
返回5行,正如预期的那样。现在运行以下查询:
USE [test]
SELECT [column1]
FROM [test].[dbo].[table1]
WHERE [column1] IN
(SELECT TOP 5 [test].[dbo].[table1].[column1]
FROM [table1])
这次返回10行,即使SELECT TOP 5 [test].[dbo].[table1].[column1] FROM [table1]
返回5行。
看看执行计划,我可以看出服务器正在做一些不同的事情,但我不知道为什么。
解决方案似乎是确保我们没有原因而过于明确,但现在我们已经遇到过,我们希望确保没有人再次导致这种行为。
答案 0 :(得分:1)
查询的上下文是产生差异的原因。
在以下查询中,第二个select语句实际上是从第一个表中选择一个列。
SELECT [column1]
FROM [test].[dbo].[table1]
WHERE [column1] IN
(SELECT TOP 5 [test].[dbo].[table1].[column1]
FROM [table1])
如果您为表格提供别名,您会注意到不同的结果:
SELECT [column1]
FROM [test].[dbo].[table1] table1A
WHERE [column1] IN
(SELECT TOP 5 [test].[dbo].[table1].[column1]
FROM [table1])
此外,当您单独运行查询SELECT TOP 5 [test].[dbo].[table1].[column1] FROM [table1]
时,不会混淆您选择的是哪个表。
您的查询相当于:
Select column1 from table1
where column1 in
(select column1)
只要另一个表返回行,您选择的值在子查询中总是等于它自己。 它非常像是在说 在添加到另一个集合时,将列值等于其自身的集合中的每个给出。只要另一个集合不为空,列值将始终等于它。