Áp dụng thất bại khi thêm DateTime


7

Khi cố gắng đạt được Pivotmục tiêu -ed cho bảng dữ liệu hai hàng thành một hàng, suy nghĩ đầu tiên của tôi là sử dụng a Cross Apply. Bằng cách sử dụng, người Cross Applyta có thể xác định / tạo từng hàng với một tên cột cụ thể được lấy từ id duy nhất của hàng. (ví dụ: 'Lat1' và 'Lat2 cho cột nguồn' Latitude ').

Tất cả đều ổn khi tôi sử dụng INThoặc FLOATloại dữ liệu nhưng khi tôi cố gắng sử dụng DateTimetất cả VALUEStrở thành DateTime.


Ví dụ Vận chuyển Lat / Long / DateTime

Chúng tôi có hai điểm trong một hành trình tàu được báo cáo vào hai ngày khác nhau:

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 thành công Nếu chúng ta sử dụng CrossApplydữ liệu cho ba cột đầu tiên

  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)

Kết quả của chúng tôi là như mong đợi:

Áp dụng thành công với Int và Float

Tuyệt quá!


Thất bại chéo với DateTime

Nhưng một khi chúng ta thêm DateTimevào hỗn hợp:

      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)

Tất cả trở thành DateTimes

Áp dụng thất bại với DateTime

Làm thế nào một người nên làm việc xung quanh điều này nếu mục tiêu cuối cùng của tôi là xoay tất cả các giá trị từ bảng gốc thành một hàng?

Câu trả lời:


14

Trong kết quả, cột giá trị phải có kiểu dữ liệu, như mọi khi. SQL Server xác định loại sử dụng các quy tắc cho quyền ưu tiên loại dữ liệu (chính xác hơn, VALUESmệnh đề là a UNION, vì vậy các loại được khớp ở đó).

Trong ví dụ đầu tiên của bạn, các quy tắc ưu tiên đưa ra một cột kiểu float . Trong ví dụ thứ hai, nó là datetime .

Giải quyết vấn đề bằng cách chuyển rõ ràng từng giá trị trong VALUESmệnh đề thành một loại phổ biến, ví dụ varchar hoặc 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);

hoặc là:

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);

Lưu ý: Không phải mọi thứ đều có thể được chuyển thành sql_variant . Từ liên kết đó:

Những hạn chế

Tất cả mọi thứ ngoại trừ loại hình ảnh không dùng cũ có thể được chuyển thành char hoặc varchar . Xem ma trận chuyển đổi trong Chuyển đổi loại dữ liệu (Công cụ cơ sở dữ liệu) :

Ma trận chuyển đổi

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.