Dưới đây là một phiên bản giả UNPIVOT cho phép bạn chỉ định thứ tự của các cột (nếu các tên cột không sắp xếp theo vị trí của chúng).
SELECT
T.ID,
X.Name
FROM
T
CROSS APPLY (
SELECT TOP 1 Name FROM (
VALUES (1, 'A1', T.A1), (2, 'A2', T.A2), (3, 'A3', T.A3), (4, 'A4', T.A4),
(5, 'A5', T.A5), (6, 'A6', T.A6), (7, 'A7', T.A7), (8, 'A8', T.A8),
(9, 'A9', T.A9)
) X (Pos, Name, Col)
WHERE Col IS NOT NULL
ORDER BY X.Pos DESC
) X;
Tuy nhiên, trong khi thực tế IO và CPU không phải là tồi tệ hơn nhiều so với phương pháp UNPIVOT tự nhiên (kế hoạch thực hiện trông xấu, nhưng tác động máy chủ thực sự không phải là tồi tệ hơn nhiều), đây không phải là người biểu diễn tốt nhất. Biểu thức CASE đơn giản được đưa ra bởi @pst là.
Giả sử các tên cột thể được sắp xếp như là, UNPIVOT có thể được đơn giản hóa hơn nữa:
SELECT ID, Max(Last)
FROM T UNPIVOT (Value FOR Last IN (A1, A2, A3, A4, A5, A6, A7, A8, A9)) U
GROUP BY ID;
Cuối cùng, đây là một phiên bản điên Tôi nghĩ về điều đó không may thực hiện tồi tệ hơn những người khác:
SELECT
T.ID,
Coalesce(
(SELECT 'A9' WHERE T.A9 IS NOT NULL),
(SELECT 'A8' WHERE T.A8 IS NOT NULL),
(SELECT 'A7' WHERE T.A7 IS NOT NULL),
(SELECT 'A6' WHERE T.A6 IS NOT NULL),
(SELECT 'A5' WHERE T.A5 IS NOT NULL),
(SELECT 'A4' WHERE T.A4 IS NOT NULL),
(SELECT 'A3' WHERE T.A3 IS NOT NULL),
(SELECT 'A2' WHERE T.A2 IS NOT NULL),
(SELECT 'A1' WHERE T.A1 IS NOT NULL)
) LastNotNullColumn
FROM T
ORDER BY ID
Về mặt lý thuyết, động cơ có thể đưa ra một kế hoạch trông rất giống với phiên bản biểu thức CASE, nhưng không. Kế hoạch này trông hoàn toàn điên rồ, với một đối tượng bảng cho mỗi câu lệnh select, và mất khoảng hai lần CPU như là biểu thức CASE.
Tất cả các phiên bản tôi đã thử nghiệm sử dụng cùng một số lần đọc logic, chỉ thay đổi trong CPU. Tôi đã sử dụng 15.000 hàng để kiểm tra.
Cuối cùng, tôi không thể trong lương tâm tốt không cảnh báo bạn rằng lược đồ của bạn có lẽ không tốt nhất. Mặc dù tôi không thể biết dữ liệu của bạn là gì, nhưng bạn đang cố gắng tìm dữ liệu cuối cùng có thể gợi ý các cột đại diện cho thời gian hoặc giai đoạn của một số vòng đời - và đó không phải là thiết kế cơ sở dữ liệu chính xác. Thay vào đó, lưu trữ dữ liệu không được bỏ phiếu. Khi thời gian đến mà bạn cần một tập kết quả được xoay vòng, bạn có thể PIVOT. Và, việc truy vấn giá trị gần đây nhất cho mỗi ID trở nên đơn giản hơn một chút!
Tôi có thể nói "giản đồ đó trông khủng khiếp" không? :-) Nó có thể được thực hiện với một ưu tiên đảo ngược có điều kiện. –