sql >> Databáze >  >> RDS >> Sqlserver

Křížový dotaz s dynamickými sloupci v SQL Server 2005 nahoru

PIVOT lze provést dvěma způsoby statické, kde pevně zakódujete hodnoty, a dynamické, kde se sloupce určují při spuštění.

I když budete chtít dynamickou verzi, někdy je jednodušší začít se statickým PIVOT a poté pracujte na dynamickém.

Statická verze:

SELECT studentid, name, sex,[C], [C++], [English], [Database], [Math], total, average
from 
(
  select s1.studentid, name, sex, subjectname, score, total, average
  from Score s1
  inner join
  (
    select studentid, sum(score) total, avg(score) average
    from score
    group by studentid
  ) s2
    on s1.studentid = s2.studentid
) x
pivot 
(
   min(score)
   for subjectname in ([C], [C++], [English], [Database], [Math])
) p

Viz SQL Fiddle s ukázkou

Nyní, pokud neznáte hodnoty, které budou transformovány, můžete k tomu použít Dynamic SQL:

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(SubjectName) 
                    from Score
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')



set @query = 'SELECT studentid, name, sex,' + @cols + ', total, average
              from 
             (
                select s1.studentid, name, sex, subjectname, score, total, average
                from Score s1
                inner join
                (
                  select studentid, sum(score) total, avg(score) average
                  from score
                  group by studentid
                ) s2
                  on s1.studentid = s2.studentid
            ) x
            pivot 
            (
                min(score)
                for subjectname in (' + @cols + ')
            ) p '

execute(@query)

Viz SQL Fiddle s ukázkou

Obě verze přinesou stejné výsledky.

Jen pro doplnění odpovědi, pokud nemáte PIVOT pak můžete tento výsledek získat pomocí CASE a agregační funkce:

select s1.studentid, name, sex, 
  min(case when subjectname = 'C' then score end) C,
  min(case when subjectname = 'C++' then score end) [C++],
  min(case when subjectname = 'English' then score end) English,
  min(case when subjectname = 'Database' then score end) [Database],
  min(case when subjectname = 'Math' then score end) Math,
  total, average
from Score s1
inner join
(
  select studentid, sum(score) total, avg(score) average
  from score
  group by studentid
) s2
  on s1.studentid = s2.studentid
group by s1.studentid, name, sex, total, average

Viz SQL Fiddle s ukázkou



  1. Spuštění kontejneru docker vyžaduje alespoň 1 argument

  2. MySql Regex Expression test

  3. ORA-00932:nekonzistentní datové typy:očekávaný počet NUMBER je DLOUHÝ

  4. Jak povolit omezení cizího klíče v SQL Server (příklady T-SQL)