Sql-Server

添加日期時間時交叉應用失敗

  • April 18, 2016

在嘗試實現將Pivot兩行數據表合併為一行的 -ed 目標時,我的第一個想法是使用Cross Apply. 通過使用Cross Apply它可以辨識/生成具有從行的唯一 ID 派生的特定列名稱的每一行。(例如,“Latitude”源列的“Lat1”和“Lat2”)。

INT當我使用or數據類型時一切都很好,FLOAT但是當我嘗試使用DateTimeall VALUESbecome時DateTime


範例運輸 Lat/Long/DateTime

我們在兩個不同的日子報告了一次船舶旅程中的兩點:

CREATE TABLE #Shipping
(
    [RouteID]     [INT]  NOT NULL,
    [Latitude]    FLOAT NOT NULL, 
    [Longitude]   FLOAT NOT NULL,
    [Time]        DATETIME NOT NULL

);

INSERT #Shipping(RouteID, [Latitude], [Longitude], [Time])
VALUES          (1,         18.0221,    -63.1206,  '24-Jan-2016'), 
               (2,         17.8353,    -62.99667, '25-Jan-2016');

成功的 CrossApply 如果我們CrossApply針對前三列的數據使用

 SELECT  col+cast([RouteID] as varchar(1)) new_col
        , X.value
      FROM #Shipping
 CROSS APPLY
 (
     VALUES
        (RouteID,   'Id')
     ,  (Latitude,  'Lat')
     ,  (Longitude, 'Lon')
 ) X (value, col)

我們的結果符合預期:

使用 Int 和 Float 交叉應用成功

偉大的!


與 DateTime 交叉應用失敗

但是一旦我們添加DateTime到混合中:

     SELECT  col+cast([RouteID] as varchar(1)) new_col
            , X.value
          FROM #Shipping
     CROSS APPLY
     (
         VALUES
            (RouteID,   'Id')
         ,  (Latitude,  'Lat')
         ,  (Longitude, 'Lon')
         , ([Time],    'Time')
     ) X (value, col)

都變成DateTime

DateTime 交叉應用失敗

如果我的最終目標是將原始表中的所有值轉換為一行,應該如何解決這個問題?

結果,列必須有一個數據類型,就像往常一樣。SQL Server 使用數據類型優先級規則確定類型(更準確地說,VALUES子句是 a UNION,因此類型在那裡匹配)。

在您的第一個範例中,優先規則給出了float類型的列。在第二個範例中,它是datetime

通過將子句中的每個值VALUES顯式轉換為通用類型來解決問題,例如varcharsql_variant

SELECT
   new_col = X.col + CAST(S.RouteID as varchar(10)),
   X.value
FROM #Shipping AS S
CROSS APPLY
(
   VALUES
       (CONVERT(sql_variant, S.RouteID),   'Id'),
       (CONVERT(sql_variant, S.Latitude),  'Lat'),
       (CONVERT(sql_variant, S.Longitude), 'Lon'),
       (CONVERT(sql_variant, S.[Time]), 'Time')
) AS X (value, col);

要麼:

SELECT
   new_col = X.col + CAST(S.RouteID as varchar(10)), 
   X.value
FROM #Shipping AS S
CROSS APPLY
(
   VALUES
       (CONVERT(varchar(8), S.RouteID),   'Id'),
       (CONVERT(varchar(8), S.Latitude),  'Lat'),
       (CONVERT(varchar(8), S.Longitude), 'Lon'),
       (CONVERT(varchar(8), S.[Time], 112), 'Time')
) AS X (value, col);

注意:並非所有內容都可以轉換為sql_variant。從那個連結:

限制

除了舊的不推薦使用的圖像類型之外的所有內容都可以轉換為charvarchar請參閱數據類型轉換(數據庫引擎)中的轉換矩陣:

轉換矩陣

引用自:https://dba.stackexchange.com/questions/135587