2010-06-30 49 views
5

我很奇怪,爲什麼下面的失敗:是否有任何理由不能在SQL Server中選擇語句?

SELECT price<500 as PriceIsCheap 

,並迫使你做到以下幾點:

SELECT CASE WHEN (price<500) THEN 1 ELSE 0 END as PriceIsCheap 

時,as per the answer to this related questionconversion table說,隱式轉換應該發生。

+0

編輯:改變了示例條件,因爲顯然'1 = 1'作爲佔位符使問題變得棘手。 – 2010-06-30 05:29:24

+1

給出一個問題的最簡單的例子是一個很好的習慣,通常情況下 - 很明顯你不需要'SELECT 1',因爲那時你已經寫了這個。 – Amadan 2010-06-30 05:32:33

+0

直到幾個版本之前,SQL Server中的「bit」類型不能爲空。由於比較可能導致TRUE,FALSE或UNKNOWN,因此無法表示UNKNOWN。如果您不認爲UNKNOWN與NULL相同,則仍然無法表示它。 – Gabe 2010-06-30 05:34:23

回答

6

在SQL沒有布爾數據類型,BIT是怎樣的一個黑客,但主要的問題是,由於NULL真正boolean logic的SQL概念是不可能的(例如,你會查詢返回如果priceNULL ?)

注意,我並不是說,有沒有可能方式實現布爾邏輯「大多是」工作(例如,你可以說TRUE OR NULLNULL或其他)只是誰設計的人SQL標準無法確定布爾邏輯的唯一真實表示(例如,您也可以爭辯說TRUE OR NULLTRUE,因爲TRUE OR <anything>TRUE)。

的布爾表達式(=,= <,> =等)僅在某些地方有效(尤其是WHERE條款和CASE標籤),而不是在其他任何地方。

+1

酷,我現在希望這個位可以是空的,他們可以解決這個問題,因爲很顯然,他們*已經決定了布爾邏輯的唯一真實表示以用於評估。有趣的是,你不能比較布爾值 - (SELECT CASE WHEN(1 = 1)=(1 = 1)THEN 1 ELSE 0 END)失敗 – 2010-06-30 05:53:03

+1

AFAIC,TRUE或NULL = TRU E',不知道(無論MS說)。 http://dev.mysql.com/doc/refman/5.0/en/logical-operators.html和http://www.postgresql.org/docs/8.2/static/functions-logical.html同意我的看法。儘管SQL沒有對它進行定義,但它是如此有用,以至於沒有任何特定實現的藉口不這樣做。 – Amadan 2010-06-30 07:23:47

+0

在供應商之間轉換SQL語句時,需要注意一點。 – 2010-06-30 09:07:13

0

我不是MSSQL的人,但我遇到了與Oracle相同的問題。簡單的答案是,因爲在這些數據庫中布爾值不是有效的列類型。現在,爲什麼他們決定你不需要布爾值,因爲值是任何人的猜測。

@paxdiablo,這是缺少點... OP的例子只是一個最小的例子。這仍然是一個簡單而實際的例子:考慮一個People表,包含名字和年齡。你想得到所有的人,但也想知道他們是否未成年。在MySQL和PostgreSQL的,你可以寫

SELECT name, age < 18 AS minor FROM people 
+0

煩人的事情是你*可*做CASE WHEN(intColumn)THEN truthValue ELSE falseValue END。所以它可以將int轉換爲布爾值,但不是布爾值。 – 2010-06-30 05:33:35

+1

確實。我剛剛檢查了TSQL文檔 - '<'的結果是布爾值('TRUE'或'FALSE',但這種數據類型甚至沒有在「數據類型」一文中提及 - 但它們有1位整數! ,現在我也討厭MSSQL(即使從來沒有使用它) – Amadan 2010-06-30 05:35:21

+0

不知道爲什麼有人downvoted反擊我 – 2010-06-30 05:53:36

3

好吧,你還會發現,你不能,如果你有一個名爲IsCheap有點柱做SELECT * FROM STUFF WHERE IsCheap,你必須做WHERE IsCheap=1

原因很簡單,數據類型有點兒,不是布爾。誠然,它基本上是你將要使用的唯一用法,它幾乎可以被任何數據訪問框架轉換,但它在技術上還是有點0或1,而不是真正或假的布爾。有一個顯而易見的連接,我們都可以看到,但是SQL並沒有寫入這個假設,所以我們必須提供將true/false轉換爲1/0的邏輯。

+0

我也喜歡這個例子。其他供應商(MySQL/PostgreSQL)管理它 – 2010-06-30 05:40:19

2

表達式price < 500返回邏輯值:TRUE,FALSE或UNKNOWN。它不是數據值值,這就是爲什麼您需要使用CASE表達式返回相應的數據值。


FWIW Microsoft Access數據庫引擎確實將表達式的結果作爲數據值處理,例如,你可以問各種古怪的問題,例如:

SELECT 1 = 1, 1 = NULL, 1 <> NULL, 1 IN (NULL) 
    FROM Foo; 

... ...,它會很樂意提供答案,但當然,這只是證明了Access不執行SQL語言!