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

Cách đơn giản để chuyển đổi các cột và hàng trong SQL?

Có một số cách mà bạn có thể chuyển đổi dữ liệu này. Trong bài đăng ban đầu của mình, bạn đã nói rằng PIVOT có vẻ quá phức tạp đối với trường hợp này, nhưng nó có thể được áp dụng rất dễ dàng bằng cách sử dụng cả UNPIVOTPIVOT các chức năng trong SQL Server.

Tuy nhiên, nếu bạn không có quyền truy cập vào các chức năng đó, điều này có thể được sao chép bằng cách sử dụng UNION ALL thành UNPIVOT và sau đó là một hàm tổng hợp với CASE câu lệnh cho PIVOT :

Tạo bảng:

CREATE TABLE yourTable([color] varchar(5), [Paul] int, [John] int, [Tim] int, [Eric] int);

INSERT INTO yourTable
    ([color], [Paul], [John], [Tim], [Eric])
VALUES
    ('Red', 1, 5, 1, 3),
    ('Green', 8, 4, 3, 5),
    ('Blue', 2, 2, 9, 1);

Kết hợp tất cả, tổng hợp và phiên bản CASE:

select name,
  sum(case when color = 'Red' then value else 0 end) Red,
  sum(case when color = 'Green' then value else 0 end) Green,
  sum(case when color = 'Blue' then value else 0 end) Blue
from
(
  select color, Paul value, 'Paul' name
  from yourTable
  union all
  select color, John value, 'John' name
  from yourTable
  union all
  select color, Tim value, 'Tim' name
  from yourTable
  union all
  select color, Eric value, 'Eric' name
  from yourTable
) src
group by name

Xem SQL Fiddle với Demo

UNION ALL thực hiện UNPIVOT của dữ liệu bằng cách chuyển đổi các cột Paul, John, Tim, Eric thành các hàng riêng biệt. Sau đó, bạn áp dụng hàm tổng hợp sum() với case câu lệnh để nhận các cột mới cho mỗi color .

Unpivot và Pivot phiên bản tĩnh:

Cả UNPIVOTPIVOT các hàm trong máy chủ SQL làm cho việc chuyển đổi này trở nên dễ dàng hơn nhiều. Nếu bạn biết tất cả các giá trị mà bạn muốn chuyển đổi, bạn có thể mã hóa chúng thành một phiên bản tĩnh để nhận được kết quả:

select name, [Red], [Green], [Blue]
from
(
  select color, name, value
  from yourtable
  unpivot
  (
    value for name in (Paul, John, Tim, Eric)
  ) unpiv
) src
pivot
(
  sum(value)
  for color in ([Red], [Green], [Blue])
) piv

Xem SQL Fiddle với Demo

Truy vấn bên trong với UNPIVOT thực hiện chức năng tương tự như UNION ALL . Nó lấy danh sách các cột và biến nó thành các hàng, PIVOT sau đó thực hiện chuyển đổi cuối cùng thành các cột.

Phiên bản tổng hợp động:

Nếu bạn có số lượng cột không xác định (Paul, John, Tim, Eric trong ví dụ của bạn) và sau đó là một số lượng màu không xác định để chuyển đổi, bạn có thể sử dụng sql động để tạo danh sách thành UNPIVOT rồi đến PIVOT :

DECLARE @colsUnpivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX)

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('yourtable') and
               C.name <> 'color'
         for xml path('')), 1, 1, '')

select @colsPivot = STUFF((SELECT  ',' 
                      + quotename(color)
                    from yourtable t
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query 
  = 'select name, '[email protected]+'
      from
      (
        select color, name, value
        from yourtable
        unpivot
        (
          value for name in ('[email protected]+')
        ) unpiv
      ) src
      pivot
      (
        sum(value)
        for color in ('[email protected]+')
      ) piv'

exec(@query)

Xem SQL Fiddle với Demo

Phiên bản động truy vấn cả yourtable và sau đó là sys.columns bảng để tạo danh sách các mục cho UNPIVOTPIVOT . Điều này sau đó được thêm vào một chuỗi truy vấn để được thực thi. Điểm cộng của phiên bản động là nếu bạn có danh sách color đang thay đổi và / hoặc names điều này sẽ tạo danh sách tại thời điểm chạy.

Cả ba truy vấn sẽ cho ra cùng một kết quả:

| NAME | RED | GREEN | BLUE |
-----------------------------
| Eric |   3 |     5 |    1 |
| John |   5 |     4 |    2 |
| Paul |   1 |     8 |    2 |
|  Tim |   1 |     3 |    9 |


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dấu thời gian trong T-Sql trong C # có nghĩa là gì?

  2. Tối ưu hóa hiệu suất XML Server XML

  3. SQL Server 2008:Làm cách nào để cấp đặc quyền cho tên người dùng?

  4. Cách sửa lỗi "dateiff function dẫn đến lỗi tràn" trong SQL Server

  5. Thay thế các dấu ngoặc kép trong SQL Server