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 |
ElenaSTL
Starting Member
10 Posts |
Posted - 2014-10-24 : 11:26:23
|
I published a solution for a task where we should compare a value from one record with a value from the next record.I made it using loop and did it only for one machine with some actual data provided by simsekm. Here is the topic:http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=196753To solve this task for several machines we need to create an outer loop for each machine.My friend S.T. made a better code with no loops and using OVER(PARTITION BY and ROW_NUMBER() function.For almost 20 years of developing reports and SQL for them I never met the situation when I should compare consecutive records and maybe this was the reason why I did not use partition. Another reason why I did not use partition was that I did not meet a good example of using it, but only confusing explanations like this:PARTITION BY is analytic, while GROUP BY is aggregate. In order to use PARTITION BY, you have to contain int with an OVER clause.Now I will show the good example made by S.T. so all SQL developers (including my daughter Olga, who is also SQL/Reports developer) can keep it in mind.--Create original test tableIF OBJECT_ID('tempdb..#Test') IS NOT NULL DROP TABLE #TestCREATE TABLE #Test(IdKey Int IDENTITY(1,1) NOT NULL, ProdDate Datetime NOT NULL, MachineId Int NOT NULL)--Populate original test tableINSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:46:49.777', 111)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:46:50.830', 111)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:46:51.883', 111)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:46:58.797', 111)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:47:04.693', 111)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:47:14.593', 111)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:47:27.393',111)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:48:56.163',111)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:49:09.564',111)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:49:12.414',111)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:50:45.163',111)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:01:21', 222)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:01:59', 222)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:03:00', 222)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:03:44', 222)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:03:59', 222)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:04:40', 222)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:10:10', 333)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:11:09', 333)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:12:30', 333)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:12:55', 333)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:13:10', 333)INSERT INTO #Test (ProdDate, MachineId) VALUES ('2014-10-22 13:14:20', 333)--Testing test table--SELECT * FROM #Test ORDER BY MachineId, ProdDate--Declare from/to parametersDECLARE @_From Datetime = '2014-10-22 13:00:00', @_To Datetime = '2014-10-22 14:00:00'--Create working tableIF OBJECT_ID('tempdb..#Temp') IS NOT NULL DROP TABLE #TempCREATE TABLE #Temp (RowN Int NOT NULL, MachineId Int NOT NULL, ProdDate Datetime NULL, NextProdDate datetime NULL)--Populate working tableINSERT INTO #Temp (RowN, MachineId, ProdDate, NextProdDate )SELECT ROW_NUMBER() OVER(PARTITION BY MachineId ORDER BY ProdDate), MachineId, ProdDate, NULLFROM #Test--Lookup for next machine's run timeUPDATE TSET T.NextProdDate = TT.ProdDateFROM #Temp T INNER JOIN #Temp TT ON T.RowN = TT.RowN - 1 AND T.MachineId = TT.MachineId--Testing working table--SELECT * FROM #Temp--Final SELECTSELECT MachineId, SUM(CASE WHEN DATEDIFF(SECOND, ProdDate, NextProdDate) < 60 THEN DATEDIFF(SECOND, ProdDate, NextProdDate) ELSE 0 END) RunningTimeInSec, SUM(CASE WHEN DATEDIFF(SECOND, ProdDate, NextProdDate) >= 60 THEN 1 ELSE 0 END)NumberOfStopsFROM #TempWHERE ProdDate BETWEEN @_From AND @_ToGROUP BY MachineIdORDER BY MachineId--Drop temp tablesDROP TABLE #TestDROP TABLE #Temp |
|
simsekm
Starting Member
20 Posts |
Posted - 2014-10-28 : 04:39:57
|
Hi,This solution is better. Thanks for your great effort. I hope this query will help to everybody who needs a solution such "islands and gaps"Regards |
|
|
simsekm
Starting Member
20 Posts |
Posted - 2014-11-26 : 09:32:13
|
Hi again,I need an answer. I want to set RunningTimeInSec value as "10" if there are 2 zero RunningTimeInSec value consecutively. So i need to detect 2 zero value of RunningTimeInSec. How can i do that?Regards |
|
|
|
|
|
|
|