2012-02-07 77 views
1

這個查詢:爲什麼OR語句給我我不想要的記錄?

select dept, job 
from organizations 
where (dept = 'Marketing' and job <> 'Sam Wise') 
or (dept = 'Marketing' and job <> 'The Precious') 

一直給有工作顯示「神偷」時,它不應該記錄。但如果我這樣寫查詢:

select dept, job 
from organizations 
where (dept = 'Marketing' and job <> 'Sam Wise') 
and (dept = 'Marketing' and job <> 'The Precious') 

然後我得到正確的記錄。 「Sam Wise」或「The Precious」沒有工作。所以我想知道,如果我對T-SQL中的AND和OR的理解是困惑的,或者對我的sql服務器來說是不可思議的。

總之,爲什麼不是第一個查詢刪除所有具有'Sam Wise'或'The Precious'作爲工作的記錄,但第二個查詢是?

+3

你知道布爾OR操作符是如何工作的嗎? – Oded 2012-02-07 21:11:45

+4

我認爲你需要(dept ='Marketing)和(job <>'Sam Wise')和(job <>'Precious') – 2012-02-07 21:14:00

回答

14

這是因爲如果你的任何一個括號OR子句被發現是真的,那麼該行就被包含在內。你的兩個條件邏輯上意味着所有行的聯合,其中工作不是'Sam Wise'或者不是'Precious'。而且所有的行都符合這些標準,因爲例如'Sam Wise'不是'The Precious',因此符合第二個條件。

這裏就是我想你試圖爲:

select dept, job 
from organizations 
where 
    dept = 'Marketing' 
    and not (
     job = 'Sam Wise' 
     or job = 'The Precious' 
    ) 

而且注意,您可以簡單地使用與運算:

select dept, job 
from organizations 
where 
    dept = 'Marketing' 
    and job <> 'Sam Wise' 
    and job <> 'The Precious' 

這是一個邏輯規律的一個很好的例子。爲了表示相同的條件(A = X OR B = Y),但表示消極(你不想在前面)它總是轉換爲NOT (A <> X AND B <> Y)。它與(A = X AND B = Y) =>NOT (A <> X OR B <> Y)的工作原理相同。在你的情況下,AB是相同的,所以你的查詢條件job相當於NOT (A = X AND A = Y),有人認爲你將永遠返回true,因爲A = X AND A = Y永遠不會是真的。由於IN()可以用來一起表示許多OR條件,所以可以用這種方式簡化查詢:(儘管不是引擎必須做的工作,它是相同的)。

select dept, job 
from organizations 
where 
    dept = 'Marketing' 
    and job not in ('Sam Wise', 'The Precious') 

我意識到這裏有點晚些時候的A = X =>A <> X翻譯簡直是否定,在這個詞的特殊查詢的意義。在最簡單的形式,邏輯規律是這樣的,給定兩個命題P1和P2:

  • NOT (P1 AND P2) =>(NOT P1 OR NOT P2)
  • NOT (P1 OR P2) =>(NOT P1 AND NOT P2)

注意,這些持有真實,太:

  • (P1 AND P2) =>NOT (NOT P1 OR NOT P2)
  • (P1 OR P2) =>NOT (NOT P1 AND NOT P2)

這些轉變,可以是真正有幫助。

+1

閃回到數字邏輯101和[德摩根定律](http://en.wikipedia.org/wiki/De_Morgan%27s_laws)。停止瘋狂! – HABO 2012-02-07 22:30:46

+1

@ user92546謝謝你的名字!我只是從經驗中直觀地瞭解法律。 – ErikE 2012-02-08 04:56:13

+1

+1值得注意的是,儘管De Morgan的定律具有三值邏輯,但它仍然堅持SQL。 – onedaywhen 2012-02-08 08:29:41

9

這兩個條款是獨立考慮的。也許嘗試:

WHERE dept = 'Marketing' AND job NOT IN ('Sam Wise', 'The Precious'); 
+0

在那裏,我給了你一個贊成票。 :) – ErikE 2012-02-09 05:03:38

3

規則的第一組匹配「神偷」和第二組的規則匹配「山姆·懷斯」

換句話說,dept = 'Marketing' AND job <> 'Sam Wise'是行,其中dept = 'Marketing' and job = 'The Precious'真,所以該行被選中。同樣,dept = 'Marketing' AND job <> 'The Precious'對於dept = 'Marketing' and job = 'Sam Wise'的行也是如此,因此行也被選中。

一個更好的查詢會是這樣:

SELECT dept, job 
FROM organizations 
WHERE 
    dept = 'Marketing' 
    and job <> 'Sam Wise' 
    and job <> 'The Precious' 
2

select語句的一部分:

where (dept = 'Marketing' and job <> 'Sam Wise') 
or (dept = 'Marketing' and job <> 'The Precious') 

意味着它將返回查詢,如果一個或另一個是真實的,或兩者兼而有之。這就是爲什麼你會得到不想要的結果。

statement1 = true OR statemet2 = true ...result true 
statement1 = false OR statemet2 = true ...result true 
statement1 = true OR statemet2 = false...result true 
statement1 = false OR statemet2 = false ...result false 

使用,只有當兩個陳述是真實的但將返回true:

statement1 = true AND statemet2 = true ...result true 
statement1 = false AND statemet2 = true ...result false 
statement1 = true AND statemet2 = false...result false 
statement1 = false AND statemet2 = false ...result false 
4

這簡直是如何或工程,如果至少有一個部分是真實的,它將返回true。 讓我們看看第一個查詢如何適用於Job =='Sam Wise'的行。

(dept = 'Marketing' and 'Sam Wise' <> 'Sam Wise') -- FALSE 
OR  
(dept = 'Marketing' and 'Sam Wise' <> 'The Precious') -- TRUE 

我們得到了FALSE OR TRUE這樣整個WHERE返回TRUE。 AND如果兩個部分都爲TRUE,則返回TRUE,這就是爲什麼第二個查詢返回預期結果的原因。

3

比方說,你有一個記錄是市場部門的Sam Wise工作。

它評估正是如此:

(dept = 'Marketing' and job <> 'Sam Wise') 
OR (dept = 'Marketing' and job <> 'The Precious') 

(TRUE and FALSE) 
OR (TRUE and TRUE) 

(FALSE) 
OR (TRUE) 

(TRUE) 

使文檔包括在內。同樣的事情,如果它是珍貴的。您的第一個查詢基本上只是確保它適用於市場營銷部門。

1

這個概念適用於數學和邏輯,並不是嚴格的編碼事物。它只是AND和OR的邏輯術語。

相關問題