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

PIVOT động, Kết quả trả về từ JOIN của hai bảng

Có thể tôi đang thiếu thứ gì đó nhưng bạn sẽ có thể PIVOT dữ liệu nhưng bạn sẽ cần triển khai row_number() để giúp tạo các cột.

Chìa khóa sẽ là sử dụng một truy vấn tương tự như:

SELECT  ONE.UserID,
  ONE.Episode,
  ONE.Value,
  TWO.Details,
  'Details'
    +cast(row_number() over(partition by one.userid, one.episode
                           order by two.details) as varchar(10)) seq
FROM TABLE1 ONE 
INNER JOIN TABLE2 Two
  ON ONE.UserID = TWO.UserID 
AND ONE.Episode = TWO.Episode

Điều này sẽ tạo một chuỗi duy nhất cho các tên cột mới, sau đó bạn có thể áp dụng PIVOT:

select userid, episode,
  value,
  details1,
  details2
from
(
  SELECT  ONE.UserID,
    ONE.Episode,
    ONE.Value,
    TWO.Details,
    'Details'
      +cast(row_number() over(partition by one.userid, one.episode
                              order by two.details) as varchar(10)) seq
  FROM TABLE1 ONE 
  INNER JOIN TABLE2 Two
    ON ONE.UserID = TWO.UserID 
  AND ONE.Episode = TWO.Episode
) d
pivot
(
  max(details)
  for seq in (Details1, Details2)
) piv;

Xem SQL Fiddle with Demo . Sau đó, bạn có thể chuyển đổi nó thành SQL động:

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

select @cols = STUFF((SELECT ',' + QUOTENAME('Details'+cast(seq as varchar(10))) 
                    from 
                    (
                      select 
                        row_number() over(partition by one.userid, one.episode
                                                order by two.details) seq
                        FROM TABLE1 ONE 
                        INNER JOIN TABLE2 Two
                          ON ONE.UserID = TWO.UserID 
                        AND ONE.Episode = TWO.Episode
                    ) d
                    group by seq
                    order by seq
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT userid, episode, value, ' + @cols + ' 
            from 
            (
             SELECT  ONE.UserID,
                ONE.Episode,
                ONE.Value,
                TWO.Details,
                ''Details''
                  +cast(row_number() over(partition by one.userid, one.episode
                                          order by two.details) as varchar(10)) seq
              FROM TABLE1 ONE 
              INNER JOIN TABLE2 Two
                ON ONE.UserID = TWO.UserID 
              AND ONE.Episode = TWO.Episode
            ) x
            pivot 
            (
                max(details)
                for seq in (' + @cols + ')
            ) p '

execute sp_executesql @query;

Xem SQL Fiddle với Demo . Mang lại cho bạn kết quả:

| USERID | EPISODE |     VALUE |  DETAILS1 |  DETAILS2 |
|--------|---------|-----------|-----------|-----------|
|      1 |       1 | VALUE 1-1 | Details 1 | Details 2 |
|      1 |       2 | VALUE 1-2 | Details 1 | Details 2 |



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Thêm ràng buộc KIỂM TRA vào một bảng hiện có trong SQL Server (T-SQL)

  2. Số sau DateTime2 có dành cho mục đích nano giây không?

  3. SQL Server 2005 và phạm vi bảng tạm thời

  4. Thay đổi đối chiếu SQL Server thành phân biệt chữ hoa chữ thường từ phân biệt chữ hoa chữ thường?

  5. Cách khắc phục “Chức năng phân vùng được liên kết tạo ra nhiều phân vùng hơn số nhóm tệp được đề cập trong lược đồ” Msg 7707 trong SQL Server