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

PIVOT / UNPIVOT в SQL Server 2008

ето T_SQL, приемайки следното:

  • Не знаете колко колони може да се появят в резултатите.
  • Опорните елементи могат да варират (затова е първото предположение).
  • Нуждаете се от специфичния ред „ChildId1, ChilDesc1, ChildId2, ChildDesc2... asd така винаги“

DECLARE@MaxCountOfChild int

-- Obtaining Maximum times a Master is used by its children
SELECT TOP 1 @MaxCountOfChild= count(*)
FROM ChildTable
GROUP BY MasterID
order by count(*) DESC


--With that number, create a string for the Pivot elements
--if you want them in the order Id1-Desc1-Id2-Desc2
DECLARE 
    @AuxforReplacing nvarchar(MAX),
    @ChildIdsandDescs nvarchar(MAX),
    @PivotElements nvarchar(MAX),
    @Counter int,
    @sql nvarchar(MAX)

SET @Counter=0
SET @AuxforReplacing=''
SET @ChildIdsandDescs=''
SET @PivotElements=''

WHILE (@Counter < @MaxCountOfChild)
begin
    SET @[email protected] +1
    SET @[email protected] + '[' +convert(varchar, @Counter)+ '],' 
    SET @[email protected] +  '[' +convert(varchar, @Counter)+ '] as ' + convert(varchar, @Counter) + ','
    SET @[email protected] + '[ChildID' + convert(varchar, @Counter)+ '],[ChildDesc' + convert(varchar, @Counter) +'],'

end
SET @PivotElements=LEFT(@PivotElements, len(@PivotElements)-1)
SET @ChildIdsandDescs=LEFT(@ChildIdsandDescs, len(@ChildIdsandDescs)-1)
SET @AuxforReplacing=LEFT(@AuxforReplacing, len(@AuxforReplacing)-1)


--print REPLACE(@AuxforReplacing, 'as ', 'as ChildId')

--print @ChildIds
--print @PivotElements


SET @sql = N'
WITH AuxTable (Masterdesc,ChildId, MasterId,ChildDesc,  NumeroenMaster) 
AS
(
SELECT M.Description as MasterDesc, C.*, RANK() OVER (PARTITION BY M.MasterId ORDER BY M.MasterId, ChildId)
FROM  MasterTable M
    INNER JOIN ChildTable C
        ON M.MasterId=C.MasterId
)

SELECT TablaMaster.MasterId,' + @ChildIdsandDescs + '
FROM 
(
    SELECT MasterId, ' + REPLACE(@AuxforReplacing, 'as ', 'as ChildId') + '
    FROM (
    SELECT MasterId, NumeroenMaster, ChildId
    FROM AuxTable) P
    PIVOT
    (
    MAX (ChildId)
    FOR NumeroenMaster IN (' + @PivotElements +')
    ) AS pvt) As TablaMaster
INNER JOIN 
(
    SELECT MasterId, ' + REPLACE(@AuxforReplacing, 'as ', 'as ChildDesc') + '
    FROM (
    SELECT MasterId, NumeroenMaster, ChildDesc
    FROM AuxTable) P
    PIVOT
    (
    MAX (ChildDesc)
    FOR NumeroenMaster IN (' + @PivotElements +')
    ) AS pvt) As TablaChild
ON TablaMaster.MasterId= TablaChild.MasterId'

EXEC sp_executesql @sql

РЕДАКТИРАНЕ:Резултатът е следният:

MasterId ChildID1 ChildDesc1 ChildID2 ChildDesc2  ChildID3 ChildDesc3 ChildID4 ChildDesc4
-------- -------- ---------- -------- ----------- -------- ---------- -------- ---------
1           1      Child1       2      Child2     NULL        NULL       NULL      NULL
2           3      Child3       4      Child4      7          Child7      8      Child8
3           5      Child5       6      Child5     NULL        NULL       NULL      NULL

Asumming this in the table ChildTable:
ChildId  MasterId  ChildDesc
-------  --------  ---------
1      1       Child1
2      1       Child2
3      2       Child3
4      2       Child4
5      3       Child5
6      3       Child5
7      2       Child7
8      2       Child8


  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?

  2. Има ли начин за достъп до стойността на предишния ред в оператор SELECT?

  3. Най-добрият подход за премахване на времева част от дата и час в SQL Server

  4. T-SQL, използващ SUM за обща сума

  5. Услуги за отчитане на SQL сървър:как да спрете изстрелването на отчет при отваряне