Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Chuyển đổi kết quả dọc thành chế độ ngang (T-SQL)

Như đã nói điều này thực sự không thể xảy ra, điều gần nhất bạn có thể nhận được là:

January2014CalculationDate | January2014PLResult | February2014CalculationDate | February2014PLResult
---------------------------+---------------------+-----------------------------+------------------
    2014-01-02             |       100           |       2014-02-03            |       300
    2014-01-03             |       200           |       2014-02-04            |       400
    NULL                   |       NULL          |       2014-02-27            |       500

Và thậm chí điều đó không đơn giản và tôi vẫn khuyên bạn nên xử lý định dạng như thế này bên ngoài sql. Bước đầu tiên là phân vùng dữ liệu theo tháng, sau đó xếp hạng các ngày trong mỗi tháng:

SELECT  CalculationDate,
        PLResult,
        CalculationMonth,
        DenseRank = DENSE_RANK() OVER(PARTITION BY CalculationMonth ORDER BY CalculationDate)
FROM    (   SELECT  CalculationDate,
                    PLResult,
                    CalculationMonth = DATEADD(MONTH, DATEDIFF(MONTH, 0, CalculationDate), 0)
            FROM    #PLResultPerDay
        ) pl;

Điều này mang lại:

CalculationDate PLResult    CalculationMonth    DenseRank
2014-01-02      100         2014-01-01          1
2014-01-03      200         2014-01-01          2
2014-02-03      300         2014-02-01          1
2014-02-04      400         2014-02-01          2
2014-02-27      500         2014-02-01          3

Sau đó, bạn có thể xoay vòng dữ liệu này:

WITH Data AS
(   SELECT  CalculationDate,
            PLResult,
            CalculationMonth,
            DenseRank = DENSE_RANK() OVER(PARTITION BY CalculationMonth ORDER BY CalculationDate)
    FROM    (   SELECT  CalculationDate,
                        PLResult,
                        CalculationMonth = DATEADD(MONTH, DATEDIFF(MONTH, 0, CalculationDate), 0)
                FROM    #PLResultPerDay
            ) pl
)
SELECT  Jan2014CalcDate = MIN(CASE WHEN CalculationMonth = '20140101' THEN CalculationDate END),
        Jan2014Result = SUM(CASE WHEN CalculationMonth = '20140101' THEN PLResult END),
        Feb2014CalcDate = MIN(CASE WHEN CalculationMonth = '20140201' THEN CalculationDate END),
        Feb2014Result = SUM(CASE WHEN CalculationMonth = '20140201' THEN PLResult END)
FROM    Data
GROUP BY DenseRank
ORDER BY DenseRank;

Điều này mang lại:

Jan2014CalcDate Jan2014Result   Feb2014CalcDate Feb2014Result
2014-01-02      100             2014-02-03      300
2014-01-03      200             2014-02-04      400
NULL            NULL            2014-02-27      500

Sau đó, vì bạn có một số tháng động, bạn cần tạo động báo cáo trên và sử dụng SP_EXECUTESQL để chạy nó:

DECLARE @SQL NVARCHAR(MAX) = '';

WITH Months AS
(   SELECT  M,
            ColName = DATENAME(MONTH, M) + DATENAME(YEAR, M),
            CharFormat = CONVERT(VARCHAR(8), M, 112)
    FROM    (   SELECT  DISTINCT M = DATEADD(MONTH, DATEDIFF(MONTH, 0, CalculationDate), 0)
                FROM    #PLResultPerDay
            ) m
)
SELECT  @SQL = 'WITH Data AS
                (   SELECT  CalculationDate,
                            PLResult,
                            CalculationMonth,
                            DenseRank = DENSE_RANK() OVER(PARTITION BY CalculationMonth ORDER BY CalculationDate)
                    FROM    (   SELECT  CalculationDate,
                                        PLResult,
                                        CalculationMonth = DATEADD(MONTH, DATEDIFF(MONTH, 0, CalculationDate), 0)
                                FROM    #PLResultPerDay
                            ) pl
                )
                SELECT  ' + 
                STUFF(( SELECT  ', ' + ColName + 'CalculationDate = MIN(CASE WHEN CalculationMonth = ''' + CharFormat + ''' THEN CalculationDate END), ' + 
                                ColName + 'PLResult = SUM(CASE WHEN CalculationMonth = ''' + CharFormat + ''' THEN PLResult END)'
                        FROM    Months
                        ORDER BY M
                        FOR XML PATH(''), TYPE
                    ).value('.', 'NVARCHAR(MAX)'), 1, 2, '') + 
                'FROM   Data
                GROUP BY DenseRank
                ORDER BY DenseRank;';

EXECUTE SP_EXECUTESQL @SQL;

Ví dụ trên SQL Fiddle

Xin lưu ý, tôi vẫn khuyên bạn không nên sử dụng kỹ thuật này và nghĩ rằng SQL nên được để lưu trữ / truy xuất dữ liệu và lớp trình bày để định dạng nó




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. IO STATISTICS trong SQL Server là gì?

  2. Chọn số lượng từ một bảng khác cho mỗi hàng trong các hàng kết quả

  3. Sử dụng TYPE_ID () để lấy ID của một loại dữ liệu trong SQL Server

  4. SQL ánh xạ thông tin đăng nhập cho người dùng hiện có

  5. Ngăn chặn việc chèn các phạm vi ngày chồng chéo bằng cách sử dụng trình kích hoạt SQL