Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come ruotare la tabella per l'anno in SQL?

Dovrai ottenere l'anno per ciascuno dei tuoi valori di data e quindi PIVOT su quei valori. È possibile utilizzare un paio di funzioni diverse in SQL Server per ottenere questo.

  • DatePart - la sintassi sarebbe DatePart(year, yourDate)
  • Anno - la sintassi è Year(yourDate)

Uno di questi restituirà l'anno per ogni data, quindi posizionerai gli anni nel tuo PIVOT come nuove colonne.

select plate, [2011], [2012], [2013], [2014], [2015], [2016], [2017]
from
(
  SELECT tnk.Plate, 
     Cast(mua.Tarih as Date) as M_Date,
     year(mua.Tarih) yr
  FROM Muayene mua 
  LEFT JOIN Tanker tnk 
    on (tnk.OID=mua.TankerId)
) d
pivot
(
  max(m_date)
  for yr in ([2011], [2012], [2013], [2014], [2015], [2016], [2017])
) piv;

Vedi Demo . Noterai che in questa query ho rimosso la colonna mua.Id . Questo perché quando esegui il pivot dei dati, raggrupperai per ogni colonna della tua query, poiché questi valori sono distinti, restituirai righe diverse. Rimuovendo la colonna dalla tua query, restituirai un risultato:

|    PLATE |       2011 |   2012 |   2013 |       2014 |       2015 |       2016 |       2017 |
|----------|------------|--------|--------|------------|------------|------------|------------|
| 34VM7969 | 2011-08-02 | (null) | (null) | 2014-08-08 | 2015-02-21 | 2016-08-19 | 2017-03-09 |

Infine, se hai un numero imprecisato di date, ti suggerirei 2 cose:usa una tabella Calendar e poi un SQL dinamico.

Quindi la tabella del calendario è solo un elenco di date che puoi utilizzare per eseguire query simili a:

create table calendar
(
  date datetime
);

insert into calendar
select '2011-01-01' union all
select '2012-01-01' union all
select '2013-01-01' union all
select '2014-01-01' union all
select '2015-01-01' union all
select '2016-01-01' union all
select '2016-01-01' union all
select '2017-01-01' union all
select '2018-01-01' 

Dovresti quindi creare un elenco degli anni in una stringa sql ed eseguire quella stringa, simile a:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(year(date)) 
                    from calendar
                    group by year(date)
                    order by year(date)
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT plate, ' + @cols + ' 
            from 
            (
              select plate, 
                m_Date = convert(varchar(10), m_date, 120), 
                year(m_date) yr
              from yourquery
            ) x
            pivot 
            (
                max(m_date)
                for yr in (' + @cols + ')
            ) p '

execute sp_executesql @query;

Vedi Demo