如何在SQL中将表转换为年份?

时间:2014-08-08 10:22:27

标签: sql sql-server-2008

我有一个查询

SELECT mua.Id,tnk.Plate,Cast(mua.Tarih as Date) as M_Date
FROM Muayene mua 
LEFT JOIN Tanker tnk on (tnk.OID=mua.TankerId)
ORDER BY mua.Id DESC

enter image description here

但我需要结果

      Id    Plate         2011         2012   2013  2014   2015   2016        2017
      5     34VM7969      2011-08-02                               
      4     34VM7969                                               2016-08-19
      3     34VM7969                                                          2017-03-19
      1     34VM7969                               2014-08-08

如何更改此结果的查询?

1 个答案:

答案 0 :(得分:1)

您需要为每个日期值获取年份,然后对这些值进行PIVOT。您可以在SQL Server中使用几个不同的函数来实现此目的。

  • DatePart - 语法为DatePart(year, yourDate)
  • Year - 语法为Year(yourDate)

其中任何一个都会返回每个日期的年份,然后您将年份作为新列放在PIVOT中。

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;

Demo。您会注意到,在此查询中,我删除了列mua.Id。这是因为当您转动数据时,您将按查询中的每一列进行分组,因为这些值是不同的,您将返回不同的行。通过从查询中删除列,您将返回结果:

|    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 |

最后,如果您的日期数量未知,那么我建议做两件事 - 使用Calendar表,然后使用动态SQL。

然后,Calendar表只是一个可用于查询的日期列表,类似于:

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' 

然后,您将在sql字符串中创建年份列表并执行该字符串,类似于:

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;

请参阅Demo