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

Cách chuyển đổi dữ liệu từ các hàng dựa trên một cột cụ thể sang một cấu trúc dữ liệu khác

Bạn có thể sử dụng chức năng bỏ chia sẻ / pivot để nhận được kết quả mà bạn muốn. Có một số cách khác nhau để bạn có thể nhận được kết quả, nếu bạn có một số giá trị hạn chế thì bạn có thể mã hóa truy vấn nhưng nếu bạn có một số lượng giá trị không xác định thì bạn sẽ cần sử dụng SQL động.

Quá trình UNPIVOT sẽ chuyển đổi nhiều cột của c1 , vv` thành nhiều hàng. Khi dữ liệu nằm trong nhiều hàng thì bạn có thể dễ dàng áp dụng hàm PIVOT. Bạn có thể sử dụng chức năng bỏ chia hoặc ÁP DỤNG CHÉO để chuyển đổi dữ liệu từ nhiều cột:

select id,
  col = 'Service'+Service+'_'+col+'_'+cast(seq as varchar(10)),
  value
from
(
  select id, service, c1, cn
    , row_number() over(partition by id
                        order by service) seq
  from yourtable
) t
cross apply
(
  select 'c1', c1 union all
  select 'cn', cn
) c (col, value)

Xem SQL Fiddle with Demo . Áp dụng chéo sẽ chuyển đổi dữ liệu của bạn sang định dạng:

| ID |           COL | VALUE |
|  1 | ServiceA_c1_1 |     5 |
|  1 | ServiceA_cn_1 |     3 |
|  1 | ServiceB_c1_2 |     2 |
|  1 | ServiceB_cn_2 |     1 |
|  2 | ServiceA_c1_1 |     9 |
|  2 | ServiceA_cn_1 |     4 |

Khi dữ liệu ở định dạng này, bạn có thể áp dụng PIVOT:

select id, ServiceA_c1_1, ServiceA_cn_1,
  ServiceB_c1_2, ServiceB_cn_2
from
(
  select id,
    col = 'Service'+Service+'_'+col+'_'+cast(seq as varchar(10)),
    value
  from
  (
    select id, service, c1, cn
      , row_number() over(partition by id
                          order by service) seq
    from yourtable
  ) t
  cross apply
  (
    select 'c1', c1 union all
    select 'cn', cn
  ) c (col, value)
) d
pivot
(
  max(value)
  for col in (ServiceA_c1_1, ServiceA_cn_1,
              ServiceB_c1_2, ServiceB_cn_2)
) piv;

Xem SQL Fiddle with Demo .

Sau đó, nếu bạn có một số lượng giá trị không xác định, bạn có thể chuyển đổi truy vấn trên thành SQL động:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',' + QUOTENAME('Service'+Service+'_'+col+'_'+cast(seq as varchar(10))) 
                    from 
                    (
                      select service, 
                        row_number() over(partition by id
                                          order by service) seq
                      from yourtable 
                    )d
                    cross apply
                    (
                      select 'c1', 1 union all
                      select 'cn', 2
                    ) c (col, so)
                    group by seq, Service, col, so
                    order by seq, so
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT id, ' + @cols + ' 
            from 
            (
              select id,
                col = ''Service''+Service+''_''+col+''_''+cast(seq as varchar(10)),
                value
              from
              (
                select id, service, c1, cn
                  , row_number() over(partition by id
                                      order by service) seq
                from yourtable
              ) t
              cross apply
              (
                select ''c1'', c1 union all
                select ''cn'', cn
              ) c (col, value)
            ) x
            pivot 
            (
                max(value)
                for col in (' + @cols + ')
            ) p '

execute sp_executesql @query;

Xem SQL Fiddle with Demo . Cả hai sẽ cho một kết quả:

| ID | SERVICEA_C1_1 | SERVICEA_CN_1 | SERVICEB_C1_2 | SERVICEB_CN_2 |
|  1 |             5 |             3 |             2 |             1 |
|  2 |             9 |             4 |        (null) |        (null) |



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tập lệnh SQL để tìm khóa ngoại cho một bảng cụ thể?

  2. Mọi khóa ngoại của SQL Server có nên có một chỉ mục phù hợp không?

  3. Làm thế nào để truy vấn các giá trị từ các nút xml?

  4. Kết hợp nhiều truy vấn không đồng bộ trong SQL - Kết quả tối đa (XYZ hàng đầu)

  5. Tìm ngắt dòng trong chuỗi văn bản trong bảng SQL?