2017-06-22 71 views
4

我有以下數據如何前1作品在SQL Server 2012

IF OBJECT_ID('TEMPDB.DBO.#t1', 'U') IS NOT NULL 
      DROP TABLE #t1; 
CREATE TABLE #t1 
    ([c1] varchar(100), [c2] varchar(10), [c3] varchar(100), [c4] varchar(100)) 
; 

INSERT INTO #t1 
    ([c1], [c2], [c3], [c4]) 
VALUES 
    (93, '60-1.1.1.', 60, 3), 
    (104, '60-1.2.1.', 60, 3), 
    (102, '60-1.1.2.', 60, 3), 
    (101, '60-1.2.2.', 60, 3), 
    (92, '60-1.1.3.', 60, 3), 
    (96, '60-1.2.3.', 60, 3), 
    (103, '60-1.1.4.', 60, 3), 
    (94, '60-1.2.4.', 60, 3), 
    (105, '60-1.2.5.', 60, 3), 
    (97, '60-1.2.6.', 60, 3), 
    (99, '60-1.2.7.', 60, 3), 
    (100, '60-1.2.8.', 60, 3), 
    (98, '60-1.2.9.', 60, 3), 
    (95, '60-1.2.10.', 60, 3), 
    (91, '60-1.2.11.', 60, 3) 
; 
select * from #t1 

表的結果如下

enter image description here

select * from #t1 order by c3,c4 

enter image description here

現在我跑了以下查詢我得到了預期的結果

select Cast(c4 AS VARCHAR(2)) + '~'+ Cast(c1 AS VARCHAR(100)) AS c5,* from #t1 

上述查詢的結果如下

enter image description here

現在我已經使用頂1獲取的記錄我所編寫的代碼如下

select top 1 Cast(c4 AS VARCHAR(2)) + '~'+ Cast(c1 AS VARCHAR(100)) AS c5,* from #t1 

的以上查詢結果如下

enter image description here

我現在已經使用頂部帶有ORDER BY子句然後我得到了以下結果

select top 1 Cast(c4 AS VARCHAR(2)) + '~'+ Cast(c1 AS VARCHAR(100)) AS c5,* 
from #t1 order by c3,c4 

enter image description here

問:爲什麼在過去的2個查詢結果的變化,如我所喜歡期待相同的結果?

讓我問你這樣:

當我沒有爲了執行前1查詢通過我得到了93的記錄值,所以當我按列與順序執行前1我希望同樣的結果。在查詢按我的設想有通過caluse無秩序的影響

在此先感謝

編輯1

甚至當我執行100個時結果是相同的

EDIT 2

  • 服務器1

其實我已經創建了一個主表並插入了上面的記錄。運行兩個不同的會話的最後兩個查詢,結果是相同的

  • 服務器2

完成在第二服務器中的上述(在服務器1相同的步驟)。運行最後兩個前1個查詢,結果在兩個會話中是相同的。

結果似乎在服務器和會話中都是相同的。

結果

enter image description here

執行計劃enter image description here

+1

第一個查詢不會使用'order by'與'top'..and第二個確實..但是,因爲在c3,c4值中有關係,除非您在'order by'中指定了不同的列,結果將是任意的。 –

+0

如果沒有'ORDER BY' –

+0

@vkp,它不會執行任何操作,但是執行100次後結果相同 – Smart003

回答

0

當你有沒有ORDER BY所產生的排序不確定性。
所以我不確定你感到如此驚訝。

+0

讓我這樣問你: 當我執行頂部1查詢沒有秩序時,我得到了93個記錄值,所以當我執行頂部1按列排序時,我期望得到相同的結果。在查詢中,根據我的假設,沒有條款 – Smart003

0

沒有正確的order by子句,由於表不一定以任何順序讀取,您將繼續得到意想不到的結果。在最後一個查詢中使用的order by語句強調了這個問題。由於所有數據都具有相同的c3,c4值,它們在返回時都具有相同的優先級。這意味着返回值的順序是未指定的。我建議查看this post以瞭解更多信息。

+0

的訂單影響,那麼爲什麼我得到了相同的結果,即使在不同的會話中執行也是如此 – Smart003

+0

關係數據庫沒有自然順序,雖然它可能顯示基於許多測試,上面說的@vkp並不一定一致。看看這個答案是一個非常類似的問題:https://stackoverflow.com/a/20050403/2461717 – sschmitz

+0

「隨機」一詞是這個答案是不正確的,不必要的混淆。值的順序是未指定的,而不是隨機的。查詢優化器不會在行的周圍進行混洗,只要相同的查詢編譯爲相同的查詢執行計劃,結果的順序就不會改變。但看似微不足道的更改可能導致具有不同順序的不同查詢執行計劃。 – hvd

9

如果你沒有一個ORDER BY條款時,SQL Server是允許呈現的結果就是了任何順序。這意味着你可以得到不同於預期的結果。即使你有一個ORDER BY子句,如果結果集中的某些記錄與同一位置相關,Sql Server可以使用它想要的順序來記錄相關記錄。

通常,當沒有指定訂單時,Sql Server將以任何最快的順序提供結果。這意味着隨着時間的推移,結果將趨於一致,依賴於諸如主鍵順序或索引順序之類的內容。在你的簡單例子中,如果這個「基礎」順序改變了,那將是令人驚訝的。

請務必記住,訂購根本不能保證。在真實的生產環境中,如果您未指定訂單,結果可能會在執行期間發生變化。出現這種情況的原因有很多,但一個基本的例子是優化,其中兩個查詢可能搭載在相同的索引或表尋找上,第二個查詢在第一個查詢中搜索。另一個原因是對錶進行統計或行計數更改,以便Sql Server決定使用(或不使用)與以前不同的索引。

因此,如果您真的在使用像TOP這樣的選擇器時關心獲取特定記錄,那麼您確實也應該使用ORDER BY,並確保您具有足夠的明確性。


對於這個特定的數據和查詢樣,你有沒有ORDER BY第一個樣本,並用ORDER BY第一個樣本,但只能通過列c3c4條款的第二樣訂貨。 這些列對每個記錄都有相同的值。這意味着Sql Server仍然可以自由地使用任何順序,因爲所有的東西都是最方便的。

但是,這並不意味着Sql Server將在第二個查詢中使用與第一個查詢中相同的順序。添加ORDER BY子句迫使Sql Server至少查看並評估結果集,然後才能知道哪個記錄屬於哪個位置,並且該進程可以改變結果在內存中的排列,使得整個新的訂單看起來像是最方便。

所以我們看看你是否關心結果,你不僅需要一個ORDER BY條款,但是這個條款必須有足夠的選擇性來保證你想要的訂單。如果您想要顯示特定的c1值,則應在ORDER BY子句中包含c1

+0

謝謝老闆,很好的解釋,我只在主要環境中使用了order by子句,但我們的問題是顯示93,但是104顯示我不知道它背後的原因。你可以解釋一下,在上面的表中,我按列順序仍然值不同 – Smart003

+0

有列是字符串/ varchar類型,不是數字/ int類型。訂購時,列不知道有數字值,並進行文本比較。在這種情況下,'1'在'9'之前,所以'104'在'93'之前。無序示例中得到93,因爲sql server查看堆順序(插入記錄的順序),並首先找到93,但在有序示例中找到了93,因爲您將其強制置頂。 –

+0

,但排序是按其他列(c3,c4)完成的,因爲您按照您的評論說你選擇的列將會對查詢結果產生影響1 – Smart003

相關問題