2017-09-05 49 views
2

我使用SQL Server。意外的SQL分割結果?

與分部合作我在這兩個查詢中收集了我的發現,您可以使用SQL Server版本重現這些查詢。

我期待從Integer公司獲得相同的價值。 因爲無論我的表中有什麼值,如果我得到意想不到的結果,我最終會遇到一個邏輯錯誤,有時很難進行調查。

SQL答:

WITH s AS (
    SELECT 'Integer' AS c, 1 AS k UNION 
    SELECT 'Float', 1 UNION 
    SELECT 'NULL', NULL 
) 
SELECT 
    c AS [Type], 
    k/10 AS       'Division', 
    CAST(k as numeric(38,4))/10 AS 'Cast', 
    COALESCE(k, 0)/10   AS 'Coalesce', 
    COALESCE(k, .0)/10   AS 'Coalesce with float' 
FROM s; 

結果A

Type  Division Cast  Coalesce Coalesce with float 
Float  0   0.100000 0   0.100000 
Integer  0   0.100000 0   0.100000 
NULL  NULL  NULL  0   0.000000 

SQL B:

WITH s AS (
    SELECT 'Integer' AS c, 1 AS k UNION 
    SELECT 'Float', .1 UNION 
    SELECT 'NULL', NULL 
) 
SELECT 
    c AS [Type], 
    k/10 AS       'Division', 
    CAST(k as numeric(38,4))/10 AS 'Cast', 
    COALESCE(k, 0)/10   AS 'Coalesce', 
    COALESCE(k, .0)/10   AS 'Coalesce with float' 
FROM s; 

結果A

Type  Division Cast  Coalesce Coalesce with float 
Float  0.010000 0.010000 0.010000 0.010000 
Integer  0.100000 0.100000 0.100000 0.100000 
NULL  NULL  NULL  0.000000 0.000000 

回答

5

你的第一張表是所有整數。

SELECT 'Float', 1 is an INT僅僅因爲您將單詞放在那裏而不是浮動。由於沒有小數位,因此它將被隱含爲INT。

然後,你知道整數除法使用整數......比如......

select 3/10是0,而不是0.3000,你將與select 3/10.0得到。如果你想返回小數/浮動,要麼分子或分母需要一個浮動(或兩者)

編輯

你最後的評論後,我明白你的問題更多。當你將不同的數據類型結合在一起時,你在第二個CTE中做了什麼,SQL Server將隱式地將它們轉換爲所有輸入所需的數據類型。 See the order of precedence here

所以,如果你只是從那個cte中選擇*,你會看到你的1被轉換爲1.0。一列只能有一個數據類型。在這個例子中,SQL Server將不得不選擇INTFLOAT。如果選擇INT,那麼您會遇到數據完整性問題。

WITH s AS (
    SELECT 'Integer' AS c, 1 AS k UNION 
    SELECT 'Float', .1 UNION 
    SELECT 'NULL', NULL 
) 

select * from s 
+0

請檢查第二條語句SELECT'Float',.1 – profimedica

+1

@profimedica在第二條語句中,您有一個小數點。這與0.1相同。第一個是缺失的,這就是爲什麼你的整數除法返回一個整數。 – scsimon

+1

我必須強調,我創建了兩個方案,意識到添加點創建浮動的效果。此外,我期待的整數除法的結果導致一個整數和浮動的結果導致浮動。這兩個例子都是第一行。意想不到的結果是在整數線上,參與者是相同的,但輸出的類型是由浮點結果決定的。 – profimedica

1

如果你想擁有這兩個數據集相同的結果,使用FLOOR()函數

SQL一個

WITH s AS (
    SELECT 'Integer' AS c, 1 AS k UNION 
    SELECT 'Float', 1 UNION 
    SELECT 'NULL', NULL 
) 
SELECT c AS [Type], 
     FLOOR(k/10) AS 'Division', 
     CAST(k as numeric(38,4))/10 AS 'Cast', 
     FLOOR(COALESCE(k, 0)/10) AS 'Coalesce', 
     COALESCE(k, .0)/10 AS 'Coalesce with float' 
FROM s; 

SQL乙

WITH s AS (
    SELECT 'Integer' AS c, 1 AS k UNION 
    SELECT 'Float', .1 UNION 
    SELECT 'NULL', NULL 
) 
SELECT 
    c AS [Type], 
    FLOOR(k/10) AS 'Division', 
    CAST(k as numeric(38,4))/10 AS 'Cast', 
    FLOOR(COALESCE(k, 0)/10) AS 'Coalesce', 
    COALESCE(FLOOR(k), .0)/10 AS 'Coalesce with float' 
FROM s; 

兩者的結果查詢

Type Division Cast  Coalesce Coalesce with float 
Float 0   0.100000 0   0.100000 
Integer 0   0.100000 0   0.100000 
NULL NULL  NULL  0   0.000000 
+1

在您的SQL B層結果中,通過oalesce:COALESCE(FLOOR(k),.0)轉換回浮動的整數。事實上,你的方法會強制結果類型,scsimon解釋了類型優先級tah決定整個列。 – profimedica