SQL下面的兩個不是一樣嗎?我的意思是功能明智應該做同樣的事情?
我期待這第一個 SQL 也應該得到結果。
SELECT *
FROM #TEST
WHERE COL1 NOT IN (SELECT COL1 FROM #TEST_1)
AND COL2 NOT IN (SELECT COL2 FROM #TEST_1)
--1 record
SELECT *
FROM #TEST
WHERE COL1 COL2 NOT IN (SELECT COL1 COL2 FROM #TEST_1)
CREATE TABLE #TEST
(
COL1 VARCHAR(10),
COL2 VARCHAR(10),
COL3 VARCHAR(10)
)
INSERT INTO #TEST VALUES ('123', '321', 'ABC')
INSERT INTO #TEST VALUES ('123', '436', 'ABC')
CREATE TABLE #TEST_1
(
COL1 VARCHAR(10),
COL2 VARCHAR(10),
COL3 VARCHAR(10)
)
INSERT INTO #TEST_1 VALUES ( '123','532','ABC')
INSERT INTO #TEST_1 VALUES ( '123','436','ABC')
--No result
SELECT *
FROM #TEST
WHERE COL1 NOT IN (SELECT COL1 FROM #TEST_1)
AND COL2 NOT IN (SELECT COL2 FROM #TEST_1)
--1 record
SELECT *
FROM #TEST
WHERE COL1 COL2 NOT IN (SELECT COL1 COL2 FROM #TEST_1)
uj5u.com熱心網友回復:
讓我們把它放到更多的背景關系中,看看你的 2 個WHERE子句,我將分別稱之為“WHERE 1”和“WHERE 2”:
--WHERE 1
WHERE COL1 NOT IN (SELECT COL1 FROM #TEST_1)
AND COL2 NOT IN (SELECT COL2 FROM #TEST_1)
--WHERE 2
WHERE COL1 COL2 NOT IN (SELECT COL1 COL2 FROM #TEST_1)
您可能已經注意到,這并不相同。事實上,從邏輯的角度和資料庫引擎處理它們的方式來看,它們是完全不同的。
WHERE 2,開始不是SARGable。這意味著您的表上的任何索引都將無法使用,并且資料引擎將不得不掃描整個表。但是,對于 WHERE 1,它是SARGable,如果您有任何索引,它們可用于執行搜索,可能有助于提高性能。
從邏輯的角度讓我們先看一下 WHERE 2。這要求 and 的連接值與andCOL1的COL2其他連接值不匹配;這意味著這些值必須在同一行。所以只有當有 value和value時才會匹配。COL1COL2'123456'Col1'123'Col2'456'
然而,對于 WHERE 1,這里的值Col1不需要在另一個表中找到,Col2也不需要找到,但它們可以在不同的行上。這就是事情的不同之處。如'123'inCol1出現在兩個表中(并且是唯一的值),NOT IN則未滿足并且不回傳任何行。
如果您想要 WHERE 2 的 SARGable 版本,我建議使用EXISTS:
--1 row
SELECT T.COL1, --Don't use *, specify your columns
T.COL2, --Qualifying your columns is important!
T.COL3
FROM #TEST T --Aliasing is important!
WHERE NOT EXISTS (SELECT 1
FROM #TEST_1 T1
WHERE T1.COL1 = T.COL1
AND T1.COL2 = T.COL2);
db<>小提琴
uj5u.com熱心網友回復:
當您以這種方式添加字串時(使用 而不是concatenation),它會添加兩個字串并為您提供數值。在第一個查詢中,您沒有添加字串,所以您所做的是:
Select all rows from #Test that values of Col1 and Col2 are not in Test1
實際上,只有第一個引數是洗掉所有內容,因為您在 col1 的兩個表中都有 123 個值。
第二個查詢對字串求和,但不是通過連接。它實際上在幕后將 varchars 轉換為數字。所以第二個查詢會:
Select all rows from #test where COL1 COL2 (its 444 at first row, and 559 in second row) are not in #Test 1
如果您在 #Test1 添加行,則值為:
For the first row COL1 COL2= 655
For the second row COL1 COL2= 559
所以只有總和為 444 的行不是 at #Test1,這就是為什么你得到 1 行的結果。
總結一下:
這就是為什么您在第二個查詢中只看到 1 行,而在第一個查詢中看不到任何記錄的原因。在第一個查詢中,只有第一個條件真正起作用并削減了一切。在第二個查詢中,SQL 引擎正在將 varchars 轉換為數字。
所以“123” “321”不是“123321”而是“444”。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/467830.html
上一篇:Transact-SQL程式:為什么我的else回圈不起作用?
下一篇:根據最小訂單值按鍵分組
