如果serial_number
實際上是每個產品都是唯一的,就像您認爲的那樣,即使Serial_Number
是唯一的,您獲得多行的原因是因爲您沒有正確別名。總之您有:
SELECT ( select distinct left(product, 6)
from dbo.QS_WIP_Errors2 err
where err.SERIAL_NUMBER = serial_number) -- NO ALIAS ON serial_number
FROM dbo.QS_defects def
在您的相關子你對第二參考serial_number
,這意味着它是不明確它是否指的是外表(def
)或所述內表中沒有別名(err
)。在名稱衝突的SQL Server的情況下,會認爲你的意思是內部表,所以你基本上有:
WHERE err.serial_number = err.serial_number
這當然將返回所有行,因爲一切都等於本身。該問題的快速示範開始:
DECLARE @T TABLE (ID INT, Name VARCHAR(20));
INSERT @T (ID, Name) VALUES (1, 'Test 1'), (2, 'Test 2');
SELECT *
FROM @T AS T1
OUTER APPLY
( SELECT CorrelatedName = Name
FROM @T AS T2
WHERE T2.ID = ID
) AS T3
WHERE T1.ID = 1;
這樣做的輸出顯示這兩個「測試1」和「測試2」作爲相關名稱返回:
ID Name CorrelatedName
----------------------------------
1 Test 1 Test 1
1 Test 1 Test 2
有了正確的別名,你只能得到單行:
DECLARE @T TABLE (ID INT, Name VARCHAR(20));
INSERT @T (ID, Name) VALUES (1, 'Test 1'), (2, 'Test 2');
SELECT *
FROM @T AS T1
OUTER APPLY
( SELECT CorrelatedName = Name
FROM @T AS T2
WHERE T2.ID = T1.ID
) AS T3
WHERE T1.ID = 1;
ID Name CorrelatedName
----------------------------------
1 Test 1 Test 1
因此,最終的查詢也許應該是:
SELECT CASE WHEN def.serial_number LIKE '550092%' THEN
( SELECT LEFT(err.Product, 6)
FROM dbo.QS_WIP_Errors2 AS err
WHERE err.serial_number = def.serial_number
)
ELSE LEFT(def.serial_number, 6)
END AS IdentNumber
FROM dbo.QS_defects AS def
WHERE def.inspect_time >= '2015-08-01'
AND def.inspect_time <= '2015-08-10';
這是一個再努力一點,但是當我寫查詢我將有資格一切 ,這種方式是立即清除每列是什麼表,像這樣的錯誤變得更加容易辨認。
1.如果它是一個簡單的選擇從一個表我可能不打擾別名,或限定列引用,但即使如此,我仍然嘗試這樣做,以防萬一我需要添加表在一個以後的日期
錯誤說明了這一切 - 您試圖從'case'的'then'項目中投射多個值 - 您可以用'TOP 1'限制選擇,但您應該調查您的數據爲什麼它不像你期望的那樣。 – StuartLC
非常感謝 - Top 1是一個很好的解決方法,我沒有想過。據我瞭解這些表,不可能將相同的SERIAL_NUMBER分配給多個產品。我將其標記爲已解決,因爲問題不在上面的代碼中 – Tobi89
不要在沒有'ORDER BY'的情況下使用'TOP 1' – alroc