| 
                
Please start any new threads on our new 
    site at https://forums.sqlteam.com.  We've got lots of great SQL Server
    experts to answer whatever question you can come up with. 
    
        | 
                
                    | 
                            
                                | Author | Topic |  
                                    | sigreesqlStarting Member
 
 
                                        6 Posts | 
                                            
                                            |  Posted - 2014-06-11 : 04:37:35 
 |  
                                            | Have been tearing my hair out for a day trying to work this one out, have tried grouping on dates and minuted intervals without success.I've got a  table with CompanyIDs and a Datinserted field where they perform a lookup on our system.  I need to group the DatInserted on set minute intervals as if they perform more than one look up in a set minute interval they only get charged once.So for example based on a 5 minute period from this table:intCompanyID	DatInserted              365	        2014-04-25 11:12:01.940 365	        2014-04-25 11:16:50.960365	        2014-06-03 11:38:40.187365	        2014-06-03 11:38:41.320365	        2014-06-03 15:49:00.223365	        2014-06-04 08:57:59.627365	        2014-06-04 08:58:20.417365	        2014-06-04 09:09:23.103365	        2014-06-04 09:10:39.967365	        2014-06-05 11:30:21.103365	        2014-06-05 11:31:06.803365	        2014-06-05 11:31:10.187I need the following groups:intCompanyID	DatInserted              Group365	        2014-04-25 11:12:01.940  1365	        2014-04-25 11:16:50.960  1365	        2014-06-03 11:38:40.187  2365	        2014-06-03 11:38:41.320  2365	        2014-06-03 15:49:00.223  3365	        2014-06-04 08:57:59.627  4365	        2014-06-04 08:58:20.417  4365	        2014-06-04 09:09:23.103  5365	        2014-06-04 09:10:39.967  5365	        2014-06-05 11:30:21.103  6365	        2014-06-05 11:31:06.803  6365	        2014-06-05 11:31:10.187  6I want to avoid using a loop if possible.  Many thanks in advance for any help! |  |  
                                    | SwePesoPatron Saint of Lost Yaks
 
 
                                    30421 Posts | 
                                        
                                          |  Posted - 2014-06-11 : 07:05:04 
 |  
                                          | [code]-- Sample dataDECLARE	@Sample TABLE	(		CompanyID SMALLINT NOT NULL,		Inserted DATETIME NOT NULL	);INSERT	@Sample	(		CompanyID,		Inserted	)VALUES	(365, '20140425 11:12:01.940'), 	(365, '20140425 11:16:50.960'),	(365, '20140603 11:38:40.187'),	(365, '20140603 11:38:41.320'),	(365, '20140603 15:49:00.223'),	(365, '20140604 08:57:59.627'),	(365, '20140604 08:58:20.417'),	(365, '20140604 09:09:23.103'),	(365, '20140604 09:10:39.967'),	(365, '20140605 11:30:21.103'),	(365, '20140605 11:31:06.803'),	(365, '20140605 11:31:10.187');-- Solution by SwePesoWITH cteSource(CompanyID, Inserted, seq)AS (	SELECT	CompanyID,		Inserted,		CASE			WHEN LAG(Inserted, 1, '19000101') OVER (PARTITION BY CompanyID ORDER BY Inserted) < DATEADD(MINUTE, -5, Inserted) THEN 1			ELSE 0		END AS seq	FROM	@Sample)SELECT	CompanyID,	Inserted,	SUM(seq) OVER (PARTITION BY CompanyID ORDER BY Inserted ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS [Group]FROM	cteSource;[/code] Microsoft SQL Server MVP, MCT, MCSE, MCSA, MCP, MCITP, MCTS, MCDBA
 |  
                                          |  |  |  
                                    | sigreesqlStarting Member
 
 
                                    6 Posts | 
                                        
                                          |  Posted - 2014-06-11 : 09:02:20 
 |  
                                          | Thank so much just what I needed - hadn't come across LAG before!   |  
                                          |  |  |  
                                    | SwePesoPatron Saint of Lost Yaks
 
 
                                    30421 Posts | 
                                        
                                          |  Posted - 2014-06-11 : 13:09:27 
 |  
                                          | No problem.That's the beauty of educating yourself and keeping yourself up to date with each new release of SQL Server. Microsoft SQL Server MVP, MCT, MCSE, MCSA, MCP, MCITP, MCTS, MCDBA
 |  
                                          |  |  |  
                                    | sigreesqlStarting Member
 
 
                                    6 Posts | 
                                        
                                          |  Posted - 2014-06-12 : 06:15:44 
 |  
                                          | This worked ok on a sample of test data but when I have a larger data set it doesn't seem to be working correctly, this is what I get - a different group should be assigned at 2014-05-01 00:05:25.140intCompanyID	DatInserted Group365	2014-05-01 00:00:37.797	1365	2014-05-01 00:01:18.827	1365	2014-05-01 00:01:59.907	1365	2014-05-01 00:02:40.723	1365	2014-05-01 00:03:21.603	1365	2014-05-01 00:04:02.360	1365	2014-05-01 00:04:43.550	1365	2014-05-01 00:05:25.140	1365	2014-05-01 00:06:06.150	1365	2014-05-01 00:06:47.197	1365	2014-05-01 00:07:29.247	1365	2014-05-01 00:08:09.837	1365	2014-05-01 00:08:50.963	1365	2014-05-01 00:09:31.807	1365	2014-05-01 00:10:13.307	1365	2014-05-01 00:10:54.193	1365	2014-05-01 00:11:35.600	1365	2014-05-01 00:12:16.780	1365	2014-05-01 00:12:57.633	1 |  
                                          |  |  |  
                                    | stepsonAged Yak Warrior
 
 
                                    545 Posts | 
                                        
                                          |  Posted - 2014-06-12 : 07:20:41 
 |  
                                          | [code];with cTEAS(	select 365 CompanyID,CAST('2014-05-01 00:00:37.797' as DATETIME)  as 	Inserted UNION ALL 	select 365,	CAST('2014-05-01 00:01:18.827' as DATETIME)   UNION ALL	select 365,	CAST('2014-05-01 00:01:59.907' as DATETIME)	 UNION ALL	select 365,	CAST('2014-05-01 00:02:40.723' as DATETIME)	 UNION ALL	select 365,	CAST('2014-05-01 00:03:21.603' as DATETIME)	 UNION ALL	select 365,	CAST('2014-05-01 00:04:02.360' as DATETIME)	 UNION ALL	select 365,	CAST('2014-05-01 00:04:43.550' as DATETIME)	 UNION ALL	select 365,	CAST('2014-05-01 00:05:25.140' as DATETIME)	 UNION ALL	select 365,	CAST('2014-05-01 00:06:06.150' as DATETIME)	 UNION ALL	select 365,	CAST('2014-05-01 00:06:47.197' as DATETIME)	 UNION ALL	select 365,	CAST('2014-05-01 00:07:29.247' as DATETIME)	 UNION ALL	select 365,	CAST('2014-05-01 00:08:09.837' as DATETIME)	 UNION ALL	select 365,	CAST('2014-05-01 00:08:50.963' as DATETIME)	 UNION ALL	select 365,	CAST('2014-05-01 00:09:31.807' as DATETIME)	 UNION ALL	select 365,	CAST('2014-05-01 00:10:13.307' as DATETIME)	 UNION ALL	select 365,	CAST('2014-05-01 00:10:54.193' as DATETIME)	 UNION ALL	select 365,	CAST('2014-05-01 00:11:35.600' as DATETIME)	 UNION ALL	select 365,	CAST('2014-05-01 00:12:16.780' as DATETIME)	 UNION ALL	select 365,	CAST('2014-05-01 00:12:57.633' as DATETIME)	),aCTEAS (select	CompanyID	,Inserted	,CONVERT(VARCHAR(30) , DATEADD(ss,-DATEPART(ss,Inserted)%60, DATEADD(mI,-DatePart (MI,Inserted)%5,Inserted)) ,120) InsertedReffrom CTE)select CompanyID ,Inserted  ,Dense_Rank() OVER(Partition by CompanyID  Order by InsertedRef) as Groups from	 	aCTEOrder by Inserted[/code][code]CompanyID	Inserted	Groups365	2014-05-01 00:00:37.797	1365	2014-05-01 00:01:18.827	1365	2014-05-01 00:01:59.907	1365	2014-05-01 00:02:40.723	1365	2014-05-01 00:03:21.603	1365	2014-05-01 00:04:02.360	1365	2014-05-01 00:04:43.550	1365	2014-05-01 00:05:25.140	2365	2014-05-01 00:06:06.150	2365	2014-05-01 00:06:47.197	2365	2014-05-01 00:07:29.247	2365	2014-05-01 00:08:09.837	2365	2014-05-01 00:08:50.963	2365	2014-05-01 00:09:31.807	2365	2014-05-01 00:10:13.307	3365	2014-05-01 00:10:54.193	3365	2014-05-01 00:11:35.600	3365	2014-05-01 00:12:16.780	3365	2014-05-01 00:12:57.633	3[/code]sabinWeb MCP |  
                                          |  |  |  
                                    | sigreesqlStarting Member
 
 
                                    6 Posts | 
                                        
                                          |  Posted - 2014-06-12 : 07:46:34 
 |  
                                          | Thanks for the reply that's close but as the groupings on 5 min intervals it won't work for say the following:datInserted             Groups  InsertedRef2014-05-27 15:09:02.567	4	2014-05-27 15:05:002014-05-27 15:11:36.860	5	2014-05-27 15:10:00I need to group on the start point of 15:09:02.567 and any records that fall within 5 minutes of that get the same group, then the next group will be within 5 mins of the next record:datInserted             Groups  2014-05-27 15:09:02.567	4	2014-05-27 15:11:36.860	4Hope that makes sense! |  
                                          |  |  |  
                                    | MuralikrishnaVeeraPosting Yak  Master
 
 
                                    129 Posts | 
                                        
                                          |  Posted - 2014-06-12 : 08:08:43 
 |  
                                          | It is easy if we loop IF OBJECT_ID('tempdb.dbo.#t1') IS NOT NULL	DROP TABLE #t1GOCREATE TABLE #test(intCompanyID int,DatInserted datetime)INSERT INTO #testSELECT 365 ,'2014-04-25 11:12:01.940' UNION ALLSELECT 365 ,'2014-04-25 11:16:50.960' UNION ALLSELECT 365 ,'2014-06-03 11:38:40.187' UNION ALLSELECT 365 ,'2014-06-03 11:38:41.320' UNION ALLSELECT 365 ,'2014-06-03 15:49:00.223' UNION ALLSELECT 365 ,'2014-06-04 08:57:59.627' UNION ALLSELECT 365 ,'2014-06-04 08:58:20.417' UNION ALLSELECT 365 ,'2014-06-04 09:09:23.103' UNION ALLSELECT 365 ,'2014-06-04 09:10:39.967' UNION ALLSELECT 365 ,'2014-06-05 11:30:21.103' UNION ALLSELECT 365 ,'2014-06-05 11:31:06.803' UNION ALLSELECT 365 ,'2014-06-05 11:31:10.187'SELECT ROW_NUMBER()OVER(ORDER BY (SELECT 1))AS'ID',intCompanyID,DatInserted INTO #t1 FROM #testDECLARE @Id int =1DECLARE @C int = 1WHILE (@Id <=(SELECT COUNT(*) FROM #test ))BEGINDECLARE @s datetime = (SELECT DatInserted FROM #t1 WHERE ID = @Id)DECLARE @String varchar(100) = (SELECT (stuff((SELECT ','+CONVERT(varchar(30),DatInserted,121)  FROM #t1 WHERE ABS (DATEDIFF(MINUTE,@s,DatInserted) ) BETWEEN 0 AND 5 FOR XML PATH('')),1,1,'')) )DECLARE @table TABLE(intCompanyID INT,DatInserted datetime,Groups INT)INSERT INTO @table SELECT intCompanyID,DatInserted,@C FROM  #t1 WHERE PATINDEX('%,' + CONVERT(varchar(30),DatInserted,121)+',%', ',' + @String + ',') > 0 DELETE FROM #t1 WHERE PATINDEX('%,' + CONVERT(varchar(30),DatInserted,121)+',%', ',' + @String + ',') > 0 IF @@rowcount<> 0BEGINSET @C  = @C  + 1ENDSET @Id = @Id + 1ENDSELECT * FROM @tableDROP TABLE #test---------------Murali KrishnaYou live only once ..If you do it right once is enough....... |  
                                          |  |  |  
                                    | sigreesqlStarting Member
 
 
                                    6 Posts | 
                                        
                                          |  Posted - 2014-06-12 : 08:44:53 
 |  
                                          | Thank you but am trying to avoid a loop as it's a very large dataset |  
                                          |  |  |  
                                    | MuralikrishnaVeeraPosting Yak  Master
 
 
                                    129 Posts | 
                                        
                                          |  Posted - 2014-06-13 : 04:52:25 
 |  
                                          | Tried my best to done it without loop ..Try this -----------------------Table to hold test data-----------------------------------------------------------------------------------------CREATE TABLE #test(intCompanyID int,DatInserted datetime)INSERT INTO #testSELECT 365 ,'2014-04-25 11:12:01.940' UNION ALLSELECT 365 ,'2014-04-25 11:16:50.960' UNION ALLSELECT 365 ,'2014-06-03 11:38:40.187' UNION ALLSELECT 365 ,'2014-06-03 11:38:41.320' UNION ALLSELECT 365 ,'2014-06-03 15:49:00.223' UNION ALLSELECT 365 ,'2014-06-04 08:57:59.627' UNION ALLSELECT 365 ,'2014-06-04 08:58:20.417' UNION ALLSELECT 365 ,'2014-06-04 09:09:23.103' UNION ALLSELECT 365 ,'2014-06-04 09:10:39.967' UNION ALLSELECT 365 ,'2014-06-05 11:30:21.103' UNION ALLSELECT 365 ,'2014-06-05 11:31:06.803' UNION ALLSELECT 365 ,'2014-06-05 11:31:10.187'--------------bringing the Next_ID date reocrds for Comparision and inserting the reulst set into another temp table---------SELECT * INTO #textFROM (SELECT	 (SELECT intCompanyID FROM (SELECT intCompanyID,RowNum = ROW_NUMBER() OVER (ORDER BY (SELECT 1)) FROM #test)a WHERE a.RowNum =number) AS intCompanyID		,(SELECT DatInserted FROM (SELECT DatInserted,RowNum   = ROW_NUMBER() OVER (ORDER BY (SELECT 1)) FROM #test)a WHERE a.RowNum =number) AS DatInserted		,(SELECT DatInserted FROM (SELECT DatInserted,RowNum = ROW_NUMBER() OVER (ORDER BY (SELECT 1)) FROM #test)a WHERE a.RowNum =number+1) AS Next_ID		, CASE		  WHEN number =1 THEN 1		  WHEN ISNULL(DATEDIFF(   MINUTE				   ,(SELECT DatInserted FROM (SELECT DatInserted,RowNum = ROW_NUMBER() OVER (ORDER BY (SELECT 1)) FROM #test)a WHERE a.RowNum =number)				   ,(SELECT DatInserted FROM (SELECT DatInserted,RowNum = ROW_NUMBER() OVER (ORDER BY (SELECT 1)) FROM #test)a WHERE a.RowNum =number+1)				  ),6)<5 				AND  DATEDIFF(   MINUTE				   ,(SELECT DatInserted FROM (SELECT DatInserted,RowNum = ROW_NUMBER() OVER (ORDER BY (SELECT 1)) FROM #test)a WHERE a.RowNum =number-1)				   ,(SELECT DatInserted FROM (SELECT DatInserted,RowNum = ROW_NUMBER() OVER (ORDER BY (SELECT 1)) FROM #test)a WHERE a.RowNum =number)				  )>5 THEN number		   ELSE (SELECT MAX(RowNum) FROM (SELECT intCompanyID,RowNum = ROW_NUMBER() OVER (ORDER BY (SELECT 1)) FROM #test)a WHERE a.RowNum <number)	      END  AS GroupNumFROM	master.dbo.spt_valuesWHERE	Type = 'P'	    AND Number <= 12 AND number <>0)a--SELECT * FROM #text--------------Final Query to achieve desired GroupNumber-------------------------------------------------SELECT intCompanyID,DatInserted,DENSE_RANK()OVER (ORDER BY GroupNum ) AS GroupNumber FROM (SELECT intCompanyID,DatInserted,CASE WHEN Next_ID IS NULL THEN (SELECT MAX(GroupNum) FROM #text T WHERE T.GroupNum<(SELECT MAX(GroupNUM) FROM #text T1)) ELSE GroupNum END AS GroupNum FROM #text)b---------------Drop tables-------------------------------------------------------------------------------DROP TABLE #textDROP TABLE #test------------------------------------------------------------------------------------------------------------------------Murali KrishnaYou live only once ..If you do it right once is enough....... |  
                                          |  |  |  
                                    | SwePesoPatron Saint of Lost Yaks
 
 
                                    30421 Posts | 
                                        
                                          |  Posted - 2014-06-13 : 06:31:53 
 |  
                                          | quote:Why? It's neither 5 minutes after previous row nor 5 minutes after the first row?Or do you want to data to be put into 5 minutes slots?Originally posted by sigreesql
 This worked ok on a sample of test data but when I have a larger data set it doesn't seem to be working correctly, this is what I get - a different group should be assigned at 2014-05-01 00:05:25.140intCompanyID	DatInserted Group365	2014-05-01 00:00:37.797	1365	2014-05-01 00:01:18.827	1365	2014-05-01 00:01:59.907	1365	2014-05-01 00:02:40.723	1365	2014-05-01 00:03:21.603	1365	2014-05-01 00:04:02.360	1365	2014-05-01 00:04:43.550	1365	2014-05-01 00:05:25.140	1365	2014-05-01 00:06:06.150	1365	2014-05-01 00:06:47.197	1365	2014-05-01 00:07:29.247	1365	2014-05-01 00:08:09.837	1365	2014-05-01 00:08:50.963	1365	2014-05-01 00:09:31.807	1365	2014-05-01 00:10:13.307	1365	2014-05-01 00:10:54.193	1365	2014-05-01 00:11:35.600	1365	2014-05-01 00:12:16.780	1365	2014-05-01 00:12:57.633	1
 
 Microsoft SQL Server MVP, MCT, MCSE, MCSA, MCP, MCITP, MCTS, MCDBA
 |  
                                          |  |  |  
                                    | SwePesoPatron Saint of Lost Yaks
 
 
                                    30421 Posts | 
                                        
                                          |  Posted - 2014-06-13 : 06:37:20 
 |  
                                          | Is this what you want? intCompanyID	DatInserted Group365	2014-05-01 00:00:37.797	1365	2014-05-01 00:01:18.827	1365	2014-05-01 00:01:59.907	1365	2014-05-01 00:02:40.723	1365	2014-05-01 00:03:21.603	1365	2014-05-01 00:04:02.360	1365	2014-05-01 00:04:43.550	1365	2014-05-01 00:05:25.140	1365	2014-05-01 00:06:06.150	2365	2014-05-01 00:06:47.197	2365	2014-05-01 00:07:29.247	2365	2014-05-01 00:08:09.837	2365	2014-05-01 00:08:50.963	2365	2014-05-01 00:09:31.807	2365	2014-05-01 00:10:13.307	2365	2014-05-01 00:10:54.193	2365	2014-05-01 00:11:35.600	3365	2014-05-01 00:12:16.780	3365	2014-05-01 00:12:57.633	3 Microsoft SQL Server MVP, MCT, MCSE, MCSA, MCP, MCITP, MCTS, MCDBA
 |  
                                          |  |  |  
                                    | SwePesoPatron Saint of Lost Yaks
 
 
                                    30421 Posts | 
                                        
                                          |  Posted - 2014-06-13 : 06:50:54 
 |  
                                          | [code]-- Prepare sample dataDECLARE	@Sample TABLE	(		CompanyID SMALLINT NOT NULL,		Inserted DATETIME NOT NULL	);-- Populate sample dataINSERT	@Sample	(		CompanyID,		Inserted	)VALUES	(365, '20140501 00:00:37.797'),	(365, '20140501 00:01:18.827'),	(365, '20140501 00:01:59.907'),	(365, '20140501 00:02:40.723'),	(365, '20140501 00:03:21.603'),	(365, '20140501 00:04:02.360'),	(365, '20140501 00:04:43.550'),	(365, '20140501 00:05:25.140'),	(365, '20140501 00:06:06.150'),	(365, '20140501 00:06:47.197'),	(365, '20140501 00:07:29.247'),	(365, '20140501 00:08:09.837'),	(365, '20140501 00:08:50.963'),	(365, '20140501 00:09:31.807'),	(365, '20140501 00:10:13.307'),	(365, '20140501 00:10:54.193'),	(365, '20140501 00:11:35.600'),	(365, '20140501 00:12:16.780'),	(365, '20140501 00:12:57.633');-- Solution by SwePesoWITH cteSource(grp, CompanyID, Inserted, tl)AS (	SELECT		1 AS grp,			CompanyID,			MIN(Inserted) AS Inserted,			DATEADD(MINUTE, 5, MIN(Inserted)) AS tl	FROM		@Sample	GROUP BY	CompanyID	UNION ALL	SELECT		c.grp + 1 AS grp,			c.CompanyID,			f.Inserted,			DATEADD(MINUTE, 5, f.Inserted) AS tl	FROM		cteSource AS c	CROSS APPLY	(				SELECT	x.Inserted,					ROW_NUMBER() OVER (ORDER BY x.Inserted) AS rn				FROM	@Sample AS x				WHERE	x.CompanyID = c.CompanyID					AND x.Inserted > DATEADD(MINUTE, 5, c.Inserted)			) AS f	WHERE		f.rn = 1)SELECT		s.CompanyID,		s.Inserted,		c.grpFROM		cteSource AS cINNER JOIN	@Sample AS s ON s.CompanyID = c.CompanyID			AND s.Inserted BETWEEN c.Inserted AND c.tlORDER BY	s.CompanyID,		s.Inserted;[/code] Microsoft SQL Server MVP, MCT, MCSE, MCSA, MCP, MCITP, MCTS, MCDBA
 |  
                                          |  |  |  
                                    | sigreesqlStarting Member
 
 
                                    6 Posts | 
                                        
                                          |  Posted - 2014-06-13 : 08:53:30 
 |  
                                          | SwePeso that is perfect!! Thanks so much!! |  
                                          |  |  |  
                                |  |  |  |  |  |