2017-08-31 47 views
1

我正在編寫一個存儲過程來填充多選控件,我想從數據庫表中取回至少100個選項,但我想確保將所有選項都帶回用戶已經選定。使用UNION出現意外的結果

現有的查詢帶回只有第100行:

SELECT TOP 100 
    t2.Id, 
    t2.value2 
FROM 
    table1 t1 
INNER JOIN 
    table2 t2 
    ON 
    t1.clientId = t2.clientId AND t1.Id = t2.Id 
WHERE 
    t1.clientId = 1 

我添加了一個UNION到這個查詢,以確保我總是選定的選項後面還有:

SELECT TOP 100 
     t2.Id, 
     t2.value2 
    FROM 
     table1 t1 
INNER JOIN 
     table2 t2 ON 
     t1.clientId = t2.clientId AND t1.Id = t2.Id 
WHERE 
     t1.clientId = 1 
UNION 
SELECT t2.id, 
     t_si.externalCertificateNumber 
    FROM table2 t2 
INNER JOIN 
     Table3 t3 
    ON t2.value = 333 

在我的一個測試例子中,有4個先前選擇的選項。其中3個將返回前100名(1不是,因此需要更新)。

我預計會回到101行,並驚訝地得到104.我認爲這是固有的DISTINCT正在工作的方式。

但是我也看到的是返回的不同的結果。隨着一些(超過3個)不同的值出現。還有一些在之前的TOP 100中沒有了!

所以我的問題是,UNION有某種內置的排序,會影響結果?或者還有其他事情在這裏發生?

-----------------------------編輯---------------- --------------

如果我改變上述查詢前5:

和先前選擇的值是:

1, Blue 
2, Green 
20, Violet 
100 Indigo 

的結果SELECT自己看起來像這樣:

1, Blue 
2, Green 
7, Red 
15, Cyan 
20, Violet 

爲SELECT和UNION結果

1, Blue 
2, Green 
33, Cyan 
20, Violet 
24, Yellow 
100, Indigo 
60, Aero 
40, Amber 
25, Black 

這是由例如從數據庫中沒有,但要注意,紅色在SELECT從SELECT與UNION

+0

? – jarlh

+0

我的猜測是,您的查詢中的第二個選擇返回多個記錄。你爲什麼期望從該查詢中獲得單個記錄? –

+0

@jarlh它返回4,這是我的預期。這是之前選擇的4個選項。 – AidanO

回答

2

我開始懷疑,加上UNION改變了 執行計劃,並且由於沒有爲了明確設置,這 是影響什麼的回來。

你是對的。

TOP 100沒有ORDER BY返回一些 100行。沒有定義返回哪些行。

沒有UNION的查詢的第一個版本返回了一組100行,第二個版本的查詢UNION返回了另一組100行。

要獲得可預測和預期的結果,您應該在使用TOP的查詢中添加ORDER BY。理想情況下,排序應該是明確的。

是的,UNION確實具有「內置」排序。如果你看執行計劃,你通常會看到它。

我更喜歡使用共表表達式(CTE)來編寫複雜的查詢,像這樣的:如果你運行第二個選擇獨立的,有多少行返回

WITH 
CTE 
AS 
(
    SELECT TOP 100 
     t2.Id, 
     t2.value2 
    FROM 
     table1 t1 
     INNER JOIN table2 t2 
      ON t1.clientId = t2.clientId 
      AND t1.Id = t2.Id 
    WHERE 
     t1.clientId = 1 
    ORDER BY 
     t2.Id 
) 
SELECT 
    Id, 
    value2 
FROM 
    CTE 

UNION 

SELECT 
    t2.id, 
    t_si.externalCertificateNumber 
FROM 
    table2 t2 
    INNER JOIN Table3 t3 ON t2.value = 333 
; 
2

UNION操作員移開失蹤重複記錄。要保留所有記錄使用UNION ALL

SELECT TOP 100 
    t2.Id, 
    t2.value2 
FROM 
    table1 t1 
    INNER JOIN 
    table2 t2 ON 
     t1.clientId = t2.clientId AND 
     t1.Id = t2.Id 
WHERE 
    t1.clientId = 1 
UNION ALL 
SELECT t2.id, t_si.externalCertificateNumber FROM table2 t2 
    INNER JOIN Table3 t3 
    ON t2.value = 333 

TOP 100查詢缺失的記錄很容易被UNION也是結果集中的不同數量的記錄來解釋,和。

+0

我同意UNION解釋不同數量的記錄,但不是不同的結果。我開始懷疑添加UNION已經改變了執行計劃,並且因爲沒有明確設置的順序,所以這影響了回來的事情。 – AidanO

+0

執行計劃與結果集應該沒有任何關係,只有得到這些結果的速度有多快。第二個查詢實際返回多少條記錄? –

+0

104個結果,當有4個先前選擇的選項時 – AidanO