2013-07-19 84 views
2

今天我們發現了SQL Server 2012 SP1的一些奇怪行爲。我們知道如何重現問題,但我們不確定是什麼原因造成的。這裏是一個非常廣義的例子:Select語句「where in」返回的子行數多於行


假設你有一個數據庫,測試,有一個表,表1,具有下列數據:

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行。


看看執行計劃,我可以告訴服務器正在做一些不同的事情,但我不知道爲什麼。

該解決方案似乎是爲了確保我們不會無緣無故地過於明確,但現在我們遇到了,我們希望確保沒有人再次導致此行爲。

回答

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) 

只要其他表返回行,您選擇的值總是要在子查詢等於本身。 它幾乎就像是說 給我的每一列值等於自己添加到另一組時。只要另一個集合不是空的,列值將始終等於它自己。 「

+0

」在以下查詢中,第二個select語句實際上是從第一個表中選擇一列。「 我們知道它與上下文有關,但無法弄清楚它在做什麼。這很有道理。 –