If you will only have one value per tag per month, you can use a conditional aggregate to choose your record. I have gone for the MAX
function, but if you only have one value it is arbitrary:
DECLARE @Year INT;
SET @Year = 2013;
-- CONVERT TO A DATE TO ALLOW A SARGEABLE PREDICATE IN THE WHERE CLAUSE
DECLARE @Date SMALLDATETIME;
SET @Date = CONVERT(SMALLDATETIME, CONVERT(CHAR(4), @Year) + '0101', 112);
SELECT Tagname,
Jan = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 1 THEN value END),
Feb = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 2 THEN value END),
Mar = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 3 THEN value END),
Apr = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 4 THEN value END),
May = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 5 THEN value END),
Jun = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 6 THEN value END),
Jul = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 7 THEN value END),
Aug = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 8 THEN value END),
Sep = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 9 THEN value END),
Oct = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 10 THEN value END),
Nov = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 11 THEN value END),
Dec = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 12 THEN value END)
FROM runtime.dbo.History
WHERE Tagname IN ('Tag1', 'Tag2')
AND wwVersion = 'Latest'
AND DateTime >= @Date
AND DateTime < DATEADD(YEAR, 1, @Date)
GROUP BY TagName;
If you will have multiple values then you will need to apply some sort of logic to chose the correct one. In the below example I have gone for the first value for each month:
DECLARE @Year INT;
SET @Year = 2013;
-- CONVERT TO A DATE TO ALLOW A SARGEABLE PREDICATE IN THE WHERE CLAUSE
DECLARE @Date SMALLDATETIME;
SET @Date = CONVERT(SMALLDATETIME, CONVERT(CHAR(4), @Year) + '0101', 112);
SELECT Tagname,
Jan = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 1 THEN value END),
Feb = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 2 THEN value END),
Mar = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 3 THEN value END),
Apr = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 4 THEN value END),
May = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 5 THEN value END),
Jun = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 6 THEN value END),
Jul = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 7 THEN value END),
Aug = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 8 THEN value END),
Sep = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 9 THEN value END),
Oct = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 10 THEN value END),
Nov = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 11 THEN value END),
Dec = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 12 THEN value END)
FROM ( SELECT TagName,
DateTime,
Value,
RowNum = ROW_NUMBER() OVER(PARTITION BY TagName, DATEPART(MONTH, DateTime), DATEPART(YEAR, DateTime)
ORDER BY DateTime)
FROM runtime.dbo.History
WHERE Tagname IN ('Tag1', 'Tag2')
AND wwVersion = 'Latest'
AND DateTime >= @Date
AND DateTime < DATEADD(YEAR, 1, @Date)
) h
WHERE h.RowNum = 1
GROUP BY TagName;