Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Zapytanie PIVOT na rekordach Distinct

Jeśli dodasz ROW_NUMBER() do miksu, Twój wskaźnik przestawny będzie mógł zachować powiązanie między działaniami a wartościami procentowymi.

;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

Zwroty:

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

Pomysł polega na tym, że w pierwszym powszechnym wyrażeniu tabelowym przekształcasz tabelę A w następujący sposób:

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

W całym pozostałym zapytaniu kolumna ROWNUM działa tylko po to, aby powiązać wartość procentową z aktywnością.

Nadanie jej dynamiki jest łatwe, gdy masz działające zapytanie. Po prostu zamień wszystkie dynamiczne części (w tym przypadku oddzielone przecinkami listy nazw, prawda?) na zmienne. Coś takiego:

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. Aktualizacja SQL z jednej tabeli do drugiej na podstawie dopasowania ID

  2. Zwróć wartość z polecenia SQL Server Insert za pomocą c#

  3. Pobierz dzień tygodnia w SQL Server 2005/2008

  4. Funkcje TRIM, LTRIM i RTRIM programu SQL Server

  5. Zapytanie SQL „LIKE” przy użyciu „%”, gdzie kryteria wyszukiwania zawierają „%”