Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

PIVOT заявка към различни записи

Ако добавите ROW_NUMBER() към микса, вашата опорна точка ще може да запази връзката между дейности и проценти.

;with cte as 
(
    select *, ROW_NUMBER() over (partition by name order by percentage desc) ROWNUM
    from A
),
cte2 as
(
    SELECT Id,Code,ROWNUM,James,James_,Sam,Sam_,Lisa,Lisa_
    FROM cte
    PIVOT(MAX(activity)
          FOR name IN (James,Sam,Lisa)) AS PVTTable PIVOT
          (
          MAX(percentage)
          FOR name1 IN (James_,Sam_,Lisa_)) AS PVTTable1
)
select Id, Code, MAX(James) James, MAX(James_) James_, MAX(Sam) Sam, MAX(Sam_) Sam_, MAX(Lisa) Lisa, MAX(Lisa_) Lisa_
from cte2
group by Id, Code, ROWNUM

Връща:

Id  Code        James       James_  Sam         Sam_    Lisa    Lisa_
1   Prashant    Running     43.43   Cooking 1   73      Walking 90.34
1   Prashant    Stealing    0.00    Cooking     3.43    NULL    NULL
1   Prashant    Lacking     0.00    NULL        NULL    NULL    NULL

Идеята е, че в първия общ израз на таблицата трансформирате таблицата A в това:

Id  Code        percentage  name    name1   activity    ROWNUM
1   Prashant    43.43       James   James_  Running     1
1   Prashant    0.00        James   James_  Stealing    2
1   Prashant    0.00        James   James_  Lacking     3
1   Prashant    90.34       Lisa    Lisa_   Walking     1
1   Prashant    73          Sam     Sam_    Cooking 1   1
1   Prashant    3.43        Sam     Sam_    Cooking     2

И през останалата заявка колоната ROWNUM просто действа, за да обвърже процентната стойност към дейността.

Да го направите динамичен е лесно, след като имате работеща заявка. Просто заменете всички динамични части (в този случай списъци с имена, разделени със запетая, нали?) с променливи. Нещо като това:

declare @sql nvarchar(max)
declare @name_concat nvarchar(max)
declare @name1_concat nvarchar(max)
declare @select_aggs nvarchar(max)
select @name_concat = STUFF((select distinct ',' + quotename(name) from A order by 1 for xml path('')), 1, 1, '')
select @name1_concat = STUFF((select distinct ',' + quotename(name1) from A order by 1 for xml path('')), 1, 1, '')

;with cte_all_names as (
    select name from A
    union all 
    select name1 from A
)
select @select_aggs = STUFF((select distinct ',MAX(' + quotename(name) + ') ' + quotename(name) from cte_all_names order by 1 for xml path('')), 1, 1, '')

select @sql = '
;with cte as 
(
    select *, ROW_NUMBER() over (partition by name order by percentage desc) ROWNUM
    from A
),
cte2 as
(
    SELECT Id,Code,ROWNUM,' + @name_concat + ',' + @name1_concat + '
    FROM cte
    PIVOT(MAX(activity)
          FOR name IN (' + @name_concat + ')) AS PVTTable PIVOT
          (
          MAX(percentage)
          FOR name1 IN (' + @name1_concat + ')) AS PVTTable1
)
select Id, Code, ' + @select_aggs + '
from cte2
group by Id, Code, ROWNUM
'

exec sp_executesql @sql



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да създадете ограничение за проверка на множество колони в SQL Server - SQL Server / TSQL урок, част 84

  2. SQL Server:Вземете първичен ключ на таблицата с помощта на sql заявка

  3. Групово вмъкване с квалификатор на текст в SQL Server

  4. Как да намерите формата на датата, използван в текущата сесия в SQL Server (T-SQL)

  5. Как да създадете и попълните таблица в една стъпка като част от операция за импортиране на CSV?