I am trying to count difference(deduct) between two TIMEs which are all saved in one table but at different rows and columns as well. I am using SQL Server 2008 R2 Express (version 10.50.2500.0) at NT INTEL X86 Platform.
I have a table just like this one:
CREATE TABLE TBL_DATA
(
id INT IDENTITY(1,1) PRIMARY KEY,
opid INT,
lotid INT,
dt_date DATE,
dt_begin_test TIME,
dt_end_test TIME
);
This table is loaded with data / for example:
id opid lotid dt_date dt_begin_test dt_end_test
----------------------------------------------------------------------
5800 352 13381 2016-01-27 08:17:18.0000000 08:17:40.0000000
5801 352 13381 2016-01-27 08:17:49.0000000 08:18:11.0000000
5802 352 13381 2016-01-27 08:18:18.0000000 08:18:40.0000000
5803 319 13381 2016-01-27 08:18:11.0000000 08:18:33.0000000
5804 352 13381 2016-01-27 08:18:48.0000000 08:19:10.0000000
5805 352 13381 2016-01-27 08:19:18.0000000 08:19:39.0000000
5806 319 13381 2016-01-27 08:18:59.0000000 08:19:21.0000000
5807 352 13381 2016-01-27 08:19:47.0000000 08:20:09.0000000
5808 352 13381 2016-01-27 08:20:16.0000000 08:20:38.0000000
5809 319 13381 2016-01-27 08:19:59.0000000 08:20:21.0000000
5810 352 13381 2016-01-27 08:20:45.0000000 08:21:07.0000000
5811 352 13381 2016-01-27 08:21:14.0000000 08:21:36.0000000
5812 319 13381 2016-01-27 08:20:50.0000000 08:21:12.0000000
5813 352 13381 2016-01-27 08:21:43.0000000 08:22:05.0000000
5814 319 13381 2016-01-27 08:21:27.0000000 08:21:49.0000000
5815 352 13381 2016-01-27 08:22:12.0000000 08:22:33.0000000
5816 319 13381 2016-01-27 08:22:04.0000000 08:22:26.0000000
5817 352 13381 2016-01-27 08:22:41.0000000 08:23:02.0000000
What I would like to get is output for user with opid=352
, for example, where I need to deduct dt_begin_test
value of line 5805
from dt_end_test
value of line 5804
, for example. The result should be 8 seconds
. And make it for all lines of user with opid=352
.
There is a very pretty solution in case there would be only one opid
value in the table TBL_DATA
.
SELECT TBL_TEST.id,
TBL_TEST.opid,
TBL_TEST.lotid,
TBL_TEST.dt_date,
TBL_TEST.dt_begin_test,
TBL_TEST.dt_end_test,
COALESCE(
DATEDIFF(
second, (
SELECT TBL_TMP.dt_end_test
FROM [TBL_DATA] AS TBL_TMP
WHERE TBL_TMP.id = TBL_TEST.id - 1),
TBL_TEST.dt_begin_test), 0) AS PAR_DEDUCT
FROM [TBL_DATA] AS TBL_TEST
Unfortunately this solution fails in case that you must deduct values from rows which are not one after one.
I case of:
SELECT TBL_TEST.id,
TBL_TEST.opid,
TBL_TEST.lotid,
TBL_TEST.dt_date,
TBL_TEST.dt_begin_test,
TBL_TEST.dt_end_test,
COALESCE(
DATEDIFF(
second, (
SELECT TBL_TMP.dt_end_test
FROM [TBL_DATA] AS TBL_TMP
WHERE TBL_TMP.id = TBL_TEST.id - 1),
TBL_TEST.dt_begin_test), 0) AS PAR_DEDUCT
FROM [TBL_DATA] AS TBL_TEST
WHERE opid=352;
it does not work correctly what I understand.
For that I had an idea that I will use row_number()
function to create a new column and then use another select to do it. Slightly modified SELECT query as follows:
SELECT *,
COALESCE(DATEDIFF(second,
(SELECT dt_end_test FROM TBL_A AS TBL_TMP WHERE TBL_A.PAR_INDEX = TBL_TMP.PAR_INDEX - 1),
TBL_A.dt_begin_test), 0) AS PAR_DEDUCT
FROM
(SELECT row_number() OVER (ORDER BY TBL_TEST.id) AS PAR_INDEX,
TBL_TEST.id,
TBL_TEST.opid,
TBL_TEST.lotid,
TBL_TEST.dt_date,
TBL_TEST.dt_begin_test,
TBL_TEST.dt_end_test
FROM [TBL_DATA] AS TBL_TEST
WHERE opid=352
) AS TBL_A;
Unfortunately it does not work. It has a problem with TBL_A
parameter in DATEDIFF ... SELECT
statement.
I can do it in another way. I could save results in a temporary table and then do it as mentioned above. What I would like is to do it in one execution / command.
Any help is very appreciated.
Tomas.
You might be able to do what you want using Row_number in a cte and left joining it to itself.
;WITH cte AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY opid,lotid ORDER BY dt_date, dt_begin_test) Rn
FROM TBL_DATA
)
SELECT t1.*,
DATEDIFF(SECOND,t2.dt_end_test,t1.dt_begin_test)
FROM cte t1
LEFT JOIN cte t2 ON t1.opid = t2.opid
AND t1.lotid = t2.lotid
AND t1.Rn - 1 = t2.Rn
ORDER BY t1.opid,
t1.lotid,
t1.dt_date,
t1.dt_begin_test
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.