Sql-Server
添加日期時間時交叉應用失敗
在嘗試實現將
Pivot
兩行數據表合併為一行的 -ed 目標時,我的第一個想法是使用Cross Apply
. 通過使用Cross Apply
它可以辨識/生成具有從行的唯一 ID 派生的特定列名稱的每一行。(例如,“Latitude”源列的“Lat1”和“Lat2”)。
INT
當我使用or數據類型時一切都很好,FLOAT
但是當我嘗試使用DateTime
allVALUES
become時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)
我們的結果符合預期:
偉大的!
與 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
了如果我的最終目標是將原始表中的所有值轉換為一行,應該如何解決這個問題?
結果,值列必須有一個數據類型,就像往常一樣。SQL Server 使用數據類型優先級規則確定類型(更準確地說,
VALUES
子句是 aUNION
,因此類型在那裡匹配)。在您的第一個範例中,優先規則給出了float類型的列。在第二個範例中,它是datetime。
通過將子句中的每個值
VALUES
顯式轉換為通用類型來解決問題,例如varchar或sql_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。從那個連結:
除了舊的不推薦使用的圖像類型之外的所有內容都可以轉換為char或varchar。請參閱數據類型轉換(數據庫引擎)中的轉換矩陣: