4I have these tables :
day_shift
id_dshift dshift_name on_duty off_duty in_start in_end out_start out_end workday
1001 ds_normal 7:00 15:00 7:00 10:00 11:00 20:00 1
1002 ds_Saturday 7:00 14:00 7:00 10:00 11:00 14:00 1
week_shift
id_wshift wshift_name mon tue wed thu fri sat sun
2001 ws_normal 1001 1001 1001 1001 1001 1002 1001
2002 ws_2013_w1 0 1001 1001 1001 1001 1001 0
2003 ws_2013_w2 1003 1001 1001 1001 1001 1002 1001
daily_attendance
emp_id checkdate in out emp_shift_id
10 15/06/2013 7:10 15:05 2001 <-- saturday
10 16/06/2013 7:05 15:03 2001 <-- sunday
what I want is having a result like this :
emp_id checkdate in out on_duty off_duty
10 15/06/2013 7:10 15:05 07:00 14:00
10 16/06/2013 7:30 14:30 07:00 15:00
in first row of daily_attendance, since the weekday is saturday so i want to get the value of week_shift.sat (1002)
if the weekday is sunday, i want to get the value of week_shift.sun (1001)
so I get the on_duty and off_duty values from day_shift
How to do it in query?
The trick here would be to create a saved query in Access named [week_shift_transformed] to transform your [week_shift] table into separate rows for each day of the week:
SELECT id_wshift, wshift_name, 1 AS [weekday], [sun] as id_dshift FROM week_shift
UNION ALL
SELECT id_wshift, wshift_name, 2 AS [weekday], [mon] as id_dshift FROM week_shift
UNION ALL
SELECT id_wshift, wshift_name, 3 AS [weekday], [tue] as id_dshift FROM week_shift
UNION ALL
SELECT id_wshift, wshift_name, 4 AS [weekday], [wed] as id_dshift FROM week_shift
UNION ALL
SELECT id_wshift, wshift_name, 5 AS [weekday], [thu] as id_dshift FROM week_shift
UNION ALL
SELECT id_wshift, wshift_name, 6 AS [weekday], [fri] as id_dshift FROM week_shift
UNION ALL
SELECT id_wshift, wshift_name, 7 AS [weekday], [sat] as id_dshift FROM week_shift
That will give you
id_wshift wshift_name weekday id_dshift
--------- ----------- ------- ---------
2001 ws_normal 1 1001
2002 ws_2013_w1 1 0
2003 ws_2013_w2 1 1001
2001 ws_normal 2 1001
2002 ws_2013_w1 2 0
2003 ws_2013_w2 2 1003
2001 ws_normal 3 1001
2002 ws_2013_w1 3 1001
2003 ws_2013_w2 3 1001
2001 ws_normal 4 1001
2002 ws_2013_w1 4 1001
2003 ws_2013_w2 4 1001
2001 ws_normal 5 1001
2002 ws_2013_w1 5 1001
2003 ws_2013_w2 5 1001
2001 ws_normal 6 1001
2002 ws_2013_w1 6 1001
2003 ws_2013_w2 6 1001
2001 ws_normal 7 1002
2002 ws_2013_w1 7 1001
2003 ws_2013_w2 7 1002
Then you can use a query like this:
SELECT da.emp_id, da.checkdate, da.in, da.out, ds.on_duty, ds.off_duty
FROM
daily_attendance da
INNER JOIN
(
week_shift_transformed wtt
INNER JOIN
day_shift ds
ON ds.id_dshift = wtt.id_dshift
)
ON wtt.weekday = Weekday(da.checkdate)
AND wtt.id_wshift = da.emp_shift_id
Related
I have table dbo.WorkSchedules(Id, From, To) where I store date ranges for work schedules. I want to create a view that will have all dates for all rows of WorkSchedules. Thanks to this I have 1 view with all dates for all schedules.
On web I only found solutions for 1 row like 2 parameters start and end. My issue is different where I have multiple rows with start and end range.
Example:
WorkSchedules
Id | From | To
---+------------+-----------
1 | 2018-01-01 | 2018-01-05
2 | 2018-01-08 | 2018-01-12
Desired result
1 | 2018-01-01
2 | 2018-01-02
3 | 2018-01-03
4 | 2018-01-04
5 | 2018-01-05
6 | 2018-01-08
7 | 2018-01-09
8 | 2018-01-10
9 | 2018-01-11
10| 2018-01-12
If you are regularly dealing with "jobs" and "schedules" then I propose that you need a permanent calendar table (a table where each row is a unique date). You can create rows for dates dynamically but why do this many times when you can do it once and just re-use?
A calendar table, even of several decades, isn't "big" and when indexed they can be very fast as well. You can also store information about holidays and/or fiscal periods etc.
There are many scripts available to produce these tables, here's an answer with 2 scripts on this site: https://stackoverflow.com/a/5635628/2067753
Assuming you use the second (more comprehensive) script, then you can exclude weekends, or other conditions such as holidays, from query results.
Once you have a permanent Calendar table this style of query may be used:
CREATE TABLE WorkSchedules(
Id INTEGER NOT NULL PRIMARY KEY
,[From] DATE NOT NULL
,[To] DATE NOT NULL
);
INSERT INTO WorkSchedules(Id,[From],[To]) VALUES (1,'2018-01-01','2018-01-05');
INSERT INTO WorkSchedules(Id,[From],[To]) VALUES (2,'2018-01-12','2018-01-12');
with range as (
select min(ws.[From]) as dt_from, max(ws.[To]) dt_to
from WorkSchedules as ws
)
select c.*
from calendar as c
inner join range on c.date between range.dt_from and range.dt_to
where c.KindOfDay = 'BANKDAY'
order by c.date
and the result looks like this (note: "News Years Day" has been excluded)
Date Year Quarter Month Week Day DayOfYear Weekday Fiscal_Year Fiscal_Quarter Fiscal_Month KindOfDay Description
---- --------------------- ------ --------- ------- ------ ----- ----------- --------- ------------- ---------------- -------------- ----------- -------------
1 02.01.2018 00:00:00 2018 1 1 1 2 2 2 2018 1 1 BANKDAY NULL
2 03.01.2018 00:00:00 2018 1 1 1 3 3 3 2018 1 1 BANKDAY NULL
3 04.01.2018 00:00:00 2018 1 1 1 4 4 4 2018 1 1 BANKDAY NULL
4 05.01.2018 00:00:00 2018 1 1 1 5 5 5 2018 1 1 BANKDAY NULL
5 08.01.2018 00:00:00 2018 1 1 2 8 8 1 2018 1 1 BANKDAY NULL
6 09.01.2018 00:00:00 2018 1 1 2 9 9 2 2018 1 1 BANKDAY NULL
7 10.01.2018 00:00:00 2018 1 1 2 10 10 3 2018 1 1 BANKDAY NULL
8 11.01.2018 00:00:00 2018 1 1 2 11 11 4 2018 1 1 BANKDAY NULL
9 12.01.2018 00:00:00 2018 1 1 2 12 12 5 2018 1 1 BANKDAY NULL
Without the where clause the full range is:
Date Year Quarter Month Week Day DayOfYear Weekday Fiscal_Year Fiscal_Quarter Fiscal_Month KindOfDay Description
---- --------------------- ------ --------- ------- ------ ----- ----------- --------- ------------- ---------------- -------------- ----------- ----------------
1 01.01.2018 00:00:00 2018 1 1 1 1 1 1 2018 1 1 HOLIDAY New Year's Day
2 02.01.2018 00:00:00 2018 1 1 1 2 2 2 2018 1 1 BANKDAY NULL
3 03.01.2018 00:00:00 2018 1 1 1 3 3 3 2018 1 1 BANKDAY NULL
4 04.01.2018 00:00:00 2018 1 1 1 4 4 4 2018 1 1 BANKDAY NULL
5 05.01.2018 00:00:00 2018 1 1 1 5 5 5 2018 1 1 BANKDAY NULL
6 06.01.2018 00:00:00 2018 1 1 1 6 6 6 2018 1 1 SATURDAY NULL
7 07.01.2018 00:00:00 2018 1 1 1 7 7 7 2018 1 1 SUNDAY NULL
8 08.01.2018 00:00:00 2018 1 1 2 8 8 1 2018 1 1 BANKDAY NULL
9 09.01.2018 00:00:00 2018 1 1 2 9 9 2 2018 1 1 BANKDAY NULL
10 10.01.2018 00:00:00 2018 1 1 2 10 10 3 2018 1 1 BANKDAY NULL
11 11.01.2018 00:00:00 2018 1 1 2 11 11 4 2018 1 1 BANKDAY NULL
12 12.01.2018 00:00:00 2018 1 1 2 12 12 5 2018 1 1 BANKDAY NULL
and weekends and holidays may be excluded using the column KindOfDay
See this as a demonstration (with build of calendar table) here: http://rextester.com/CTSW63441
Ok, I worked this out for you, thinking you mean that you meant 01/08/2018 as a From date in the second row.
/*WorkSchedules
Id| From | To
1 | 2018-01-01 | 2018-01-05
2 | 2018-01-08 | 2018-01-12
*/
--DROP TABLE #WorkSchedules;
CREATE TABLE #WorkSchedules (
ID int,
[DateFrom] DATE,
[DateTo] DATE
)
INSERT INTO #WorkSchedules
SELECT 1, '2018-01-01', '2018-01-05'
UNION
SELECT 2, '2018-01-08', '2018-01-12'
;WITH CTEDATELIMITS AS (
SELECT [DateFrom], [DateTo]
FROM #WorkSchedules
)
,CTEDATES AS
(
SELECT [DateFrom] as [DateResult] FROM CTEDATELIMITS
UNION ALL
SELECT DATEADD(Day, 1, [DateResult]) FROM CTEDATES
JOIN CTEDATELIMITS ON CTEDATES.[DateResult] >= CTEDATELIMITS.[DateFrom]
AND CTEDATES.dateResult < CTEDATELIMITS.[DateTo]
)
SELECT [DateResult] FROM CTEDATES
ORDER BY [DateResult]
You would use a recursive CTE:
with dates as (
select from, to, from as date
from WorkSchedules
union all
select from, to, dateadd(day, 1, date)
from dates
where date < to
)
select row_number() over (order by date), date
from dates;
Note that from and to are reserved words in SQL. They are lousy names for identifiers. I have not escaped them because I assume they are not the actual names of the columns.
This is my table:
idDate timeformat timeformatdate idYear YearName idSemester semestername idquarter quartername idmonth month idweek week idday day
20160101 2016-01-01 01-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 53 W53 1 Friday , 1
20160102 2016-01-02 02-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 53 W53 2 Saturday , 2
20160103 2016-01-03 03-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 53 W53 3 Sunday , 3
20160104 2016-01-04 04-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 1 W1 4 Monday , 4
20160105 2016-01-05 05-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 1 W1 5 Tuesday , 5
20160106 2016-01-06 06-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 1 W1 6 Wednesday, 6
20160107 2016-01-07 07-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 1 W1 7 Thursday , 7
20160108 2016-01-08 08-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 1 W1 8 Friday , 8
20160109 2016-01-09 09-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 1 W1 9 Saturday , 9
20160110 2016-01-10 10-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 1 W1 10 Sunday , 10
20160111 2016-01-11 11-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 2 W2 11 Monday , 11
20160112 2016-01-12 12-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 2 W2 12 Tuesday , 12
20160113 2016-01-13 13-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 2 W2 13 Wednesday, 13
20160114 2016-01-14 14-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 2 W2 14 Thursday , 14
20160115 2016-01-15 15-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 2 W2 15 Friday , 15
20160116 2016-01-16 16-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 2 W2 16 Saturday , 16
20160117 2016-01-17 17-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 2 W2 17 Sunday , 17
20160118 2016-01-18 18-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 3 W3 18 Monday , 18
20160119 2016-01-19 19-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 3 W3 19 Tuesday , 19
20160120 2016-01-20 20-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 3 W3 20 Wednesday, 20
20160121 2016-01-21 21-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 3 W3 21 Thursday , 21
20160122 2016-01-22 22-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 3 W3 22 Friday , 22
20160123 2016-01-23 23-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 3 W3 23 Saturday , 23
20160124 2016-01-24 24-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 3 W3 24 Sunday , 24
20160125 2016-01-25 25-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 4 W4 25 Monday , 25
20160126 2016-01-26 26-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 4 W4 26 Tuesday , 26
20160127 2016-01-27 27-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 4 W4 27 Wednesday, 27
20160128 2016-01-28 28-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 4 W4 28 Thursday , 28
20160129 2016-01-29 29-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 4 W4 29 Friday , 29
20160130 2016-01-30 30-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 4 W4 30 Saturday , 30
20160131 2016-01-31 31-Jan-16 2016 2016 1 S1 1 Q1 201601 Jan 4 W4 31 Sunday , 31
I'm trying to create a time_hierarchy via a SQL statement.
What i want to achieve is for example:
Time
[2016] as Year
[Q1, 2016] as Quarter
[Jan, 2016] as Month
[Jan, 1, 2016] as Day
Etc...
I've really no idea how to achieve this or if my table do not support this kind of hierarchy.
Could you help me?
Thanks
Perhaps something like this?
SELECT
CASE WHEN quarterName IS NULL THEN 'Year'
WHEN month IS NULL THEN 'Quarter'
WHEN idDay IS NULL THEN 'Month'
ELSE 'Day'
END
AS aggregateLevel,
CASE WHEN quarterName IS NULL THEN YearName
WHEN month IS NULL THEN QuarterName || ', ' || YearName
WHEN idDay IS NULL THEN Month || ', ' || YearName
ELSE Month || ', ' || CAST(idDay AS VARCHAR(2)) || YearName
END
AS periodTitle,
MIN(idDate) AS periodFirstDate,
MAX(idDate) AS periodFinalDate
FROM
yourTable
GROUP BY
GROUPING SETS (
(YearName),
(YearName, quarterName),
(YearName, quarterName, month),
(YearName, quarterName, month, idDay)
)
ORDER BY
MIN(idDate),
MAX(idDate) DESC
I have a data frame of the format
county ones emplvl
date
2003-01-01 1001 1 10955.000000
2003-04-01 1001 1 11090.333333
2003-07-01 1001 1 11157.000000
2003-10-01 1001 1 11335.666667
2004-01-01 1001 1 11045.000000
2004-04-01 1001 1 11175.666667
2004-07-01 1001 1 11135.666667
2004-10-01 1001 1 11480.333333
2005-01-01 1001 1 11441.000000
2005-04-01 1001 1 11531.000000
2005-07-01 1001 1 11320.000000
2005-10-01 1001 1 11516.666667
2006-01-01 1001 1 11291.000000
2006-04-01 1001 1 11223.000000
2006-07-01 1001 1 11230.000000
2006-10-01 1001 1 11293.000000
2007-01-01 1001 1 11126.666667
2007-04-01 1001 1 11383.666667
2007-07-01 1001 1 11535.666667
2007-10-01 1001 1 11567.333333
2008-01-01 1001 1 11226.666667
2008-04-01 1001 1 11342.000000
2008-07-01 1001 1 11201.666667
2008-10-01 1001 1 11321.000000
2009-01-01 1001 1 11082.333333
2009-04-01 1001 1 11099.000000
2009-07-01 1001 1 10905.666667
2009-10-01 1001 1 10928.333333
2010-01-01 1001 1 10616.000000
2010-04-01 1001 1 10746.333333
2010-07-01 1001 1 10652.333333
2010-10-01 1001 1 10761.000000
2011-01-01 1001 1 10659.000000
2011-04-01 1001 1 10821.000000
2011-07-01 1001 1 10442.666667
2011-10-01 1001 1 10585.333333
2012-01-01 1001 1 10065.333333
2012-04-01 1001 1 10172.666667
2012-07-01 1001 1 10042.000000
2012-10-01 1001 1 10267.666667
and I would like to run a regression onto each group (based on values before 2007), and then add predicted values for the whole time period. The code I have right now iterates over each group. As I have hundreds of groups, it takes quite long to run:
def predictedValues(group):
sub = group[group.year < 2007]
if len(sub) == 0:
return None
regression = sm.OLS(sub.emplvl, sub[['ones', 'quarter_index']], hasconst=True).fit()
result = regression.predict(group[['ones', 'quarter_index']])
result = pd.DataFrame(data=result, columns=['predicted'], index=group.index)
return result
result = df.groupby(['county']).apply(predictedValues)
What is a more efficient way to do this? I'd prefer statsmodels over pandas, as pandas.ols is deprecated.
A little more efficient
The following runs through quite quickly, but it's atypical pandas code. So I'm still happy for improvements:
for county in df.county.unique():
group = df.loc[df.county == county]
df.loc[df.county == county, 'predicted'] = predictedValues(group)
I have a table structure as follows..
and here is sample data...
tblTeam
----------------------------------
Name TeamID
Royal Challengers Bangalore 1
Chennai Super Kings 2
Delhi Daredevils 3
Sunrisers Hyderabad 4
Kolkata Knight Riders 5
Mumbai Indians 6
Kings XI Punjab 7
Rajasthan Royals 8
Deccan Chargers 9
Kochi Tuskers Kerala 10
Pune Warriors 11
------------------------------------------------
tblSchedule
------------------------------------------------
ScheduleID DateTime Team_1 Team_2 VenuID
1 4/18/08 8:00 PM 1 5 6
2 4/19/08 5:00 PM 2 7 9
3 4/19/08 8:30 PM 3 8 4
4 4/20/08 4:30 PM 5 9 1
5 4/20/08 8:00 PM 1 6 5
6 4/21/08 8:00 PM 8 7 27
7 4/22/08 8:00 PM 3 9 10
8 4/23/08 8:00 PM 2 6 2
9 4/24/08 8:00 PM 8 9 10
10 4/25/08 8:00 PM 6 7 9
11 4/26/08 4:00 PM 5 2 2
12 4/26/08 8:00 PM 1 8 6
-----------------------------------------------
The yellow key in the pic denote primary key and blue one foreign key.
and my requirement is like this....
DateTime Team-1 Team-2
Apr 8, 2015 8:00:00 PM Kolkata Knight Riders Mumbai Indians
Please help to get that o/p...
Join tblTeam twice with different alias names (T1 & T2):
SELECT ScheduleID,DateTime,T1.Name as [Team-1],T2.Name as [Team-2]
FROM tblSchedule S JOIN
tblTeam T1 ON S.Team_1=T1.TeamID JOIN
tblTeam T2 ON S.Team_2=T2.TeamID
ORDER BY S.ScheduleID
Sample Result:
ScheduleID DateTime Team-1 Team-2
----------------------------------------------------------------------------------------
1 April, 18 2008 20:00:00 Royal Challengers Bangalore Kolkata Knight Riders
2 April, 19 2008 17:00:00 Chennai Super Kings Kings XI Punjab
3 April, 19 2008 20:30:00 Delhi Daredevils Rajasthan Royals
4 April, 20 2008 16:30:00 Kolkata Knight Riders Deccan Chargers
5 April, 20 2008 20:00:00 Royal Challengers Bangalore Mumbai Indians
Sample result in SQL Fiddle
I like to use subquery for this type of problem to avoid the extra joining
product.
SELECT
CONVERT(varchar(20), DateTime, 100) AS DateTime,
(SELECT Name FROM tblTeam WHERE s.Team_1 = TeamID) AS Team-1,
(SELECT Name FROM tblTeam WHERE s.Team_2 = TeamID) AS Team-2
FROM tblSchedule s
Extra reading
I have a query that groups aggregated sum values by month.
This is the query:
Declare #IsByStatus bit
Set #IsByStatus = 0
SELECT
CAST((DATEDIFF(month, '2012-01-01T06:00:00', datTimeStamp)) AS int) AS [Index] ,
Min(datTimeStamp) as [From],
Max(datTimeStamp) as [To],
Sum(CASE CAST(intIO_ID AS nvarchar(100))
WHEN N'284' THEN Value ELSE NULL END) AS [286]
FROM
[IOValuesFn](#IsByStatus) IOValues
WHERE
datTimeStamp >= '2012-01-01T06:00:00'
AND datTimeStamp < '2013-01-01T05:59:59'
AND intIO_ID IN (284)
GROUP BY
CAST ((DATEDIFF(Month,'2012-01-01T06:00:00', datTimeStamp)) AS int)
ORDER BY
[From]
And this is the result:
Index From To 286
0 2012-01-07 07:00:00.000 2012-01-31 23:00:00.000 142579.898864746
1 2012-02-01 00:00:00.000 2012-02-29 23:00:00.000 139486.498001099
2 2012-03-01 00:00:00.000 2012-03-31 23:00:00.000 99516.3022232056
3 2012-04-01 00:00:00.000 2012-04-30 23:00:00.000 84597.599899292
4 2012-05-01 00:00:00.000 2012-05-31 23:00:00.000 67085.2983112335
5 2012-06-01 00:00:00.000 2012-06-30 23:00:00.000 67768.9982643127
6 2012-07-01 00:00:00.000 2012-07-31 23:00:00.000 121100.264842987
7 2012-08-01 00:00:00.000 2012-08-31 23:00:00.000 165768.90776825
8 2012-09-01 00:00:00.000 2012-09-30 23:00:00.000 97441.7333068848
9 2012-10-01 00:00:00.000 2012-10-31 23:00:00.000 153764.736312866
10 2012-11-01 00:00:00.000 2012-11-30 23:00:00.000 153601.413961411
11 2012-12-01 00:00:00.000 2012-12-31 23:00:00.000 142521.07028389
12 2013-01-01 00:00:00.000 2013-01-01 05:00:00.000 1192.32000732422
Now I want to do the similar logic, that will also insert an offset in the month start-end time.
e.g. the first period will start on january 1'st on 11:00 AM and will end at february 1 10:59:59 AM.
Same goes for each subsequent month.
Thanks in advance for your help, Omer
Have a look at the example below. The trick is to add the negative amount of offset such that any hour prior to 11am on the first day of the month is "pushed" into the prior month.
Schema Setup:
create function iovaluesfn(#isbystatus bit) returns table as return
select datTimeStamp = '20130101 10:50', intIO_ID = 284, Value = 1 union all
select '20130101 11:00', 284, 1 union all
select '20130102 11:00', 284, 2 union all
select '20130301 11:00', 284, 3 union all
select '20130401 11:00', 284, 4 union all
select '20120501 11:00', 284, 5 union all
select '20120601 11:00', 284, 6 union all
select '20120101 11:00', 284, 7 union all
select '20120102 11:00', 284, 8 union all
select '20120101 11:01', 284, 9 union all
select '20120101 10:59', 284,10 union all -- ** this value is counted in Dec 2011
select '20120101 11:00', 284,11 union all
select '20120101 11:01', 281,12 union all
select '20120101 10:59', 281,13 union all
select '20120101 11:00', 281,14
GO
Query:
Declare #IsByStatus bit;
Set #IsByStatus = 0;
;with IOValues as (
select DATEADD(hour, -11, datTimeStamp) datTimeStamp, intIO_ID, Value
FROM [IOValuesFn](#IsByStatus)
WHERE datTimeStamp >= '2012-01-01T06:00:00' AND datTimeStamp < '2013-01-01T05:59:59'
AND intIO_ID IN (284)
)
SELECT CAST((DATEDIFF(month,'2012-01-01T06:00:00',datTimeStamp)) AS int) AS [Index],
Min(datTimeStamp) as [From],
Max(datTimeStamp) as [To],
Sum(CASE CAST(intIO_ID AS nvarchar(100))
WHEN N'284' THEN Value ELSE NULL END) AS [286]
FROM IOValues
GROUP BY CAST ((DATEDIFF(Month,'2012-01-01T06:00:00',datTimeStamp))AS int)
order by [From];
Results:
| INDEX | FROM | TO | 286 |
----------------------------------------------------------
| -1 | December, 31 2011 | December, 31 2011 | 10*** |
| 0 | January, 01 2012 | January, 02 2012 | 35 |
| 4 | May, 01 2012 | May, 01 2012 | 5 |
| 5 | June, 01 2012 | June, 01 2012 | 6 |
SQL Fiddle Demo