Reputation: 193
In SQL Server I have two query results like this:
I would like to use this 2 queries and then SUM the Seconds of the second table (Mains - Charging) if that specific device (43 in this case) was connected in the date range of the first table for that period using the left and right date limits. So SUM only if that condition is met.
Any suggestion on how I can accomplish this ?
This is the table script and some sample data:
First table script:
CREATE TABLE firstTable(
DeviceId INTEGER NOT NULL
,Date DATE NOT NULL
,DisplayValue VARCHAR(16) NOT NULL
,LeftLimit DATETIME NOT NULL
,RigthLimit DATETIME NOT NULL
,Seconds INTEGER NOT NULL
);
INSERT INTO firstTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Connected','2017-06-27 00:00:00.000','2017-06-27 10:17:54.460',37074);
INSERT INTO firstTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Connected','2017-06-27 10:17:54.460','2017-06-27 10:17:56.293',2);
INSERT INTO firstTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Connected','2017-06-27 10:17:56.293','2017-06-27 10:17:56.330',0);
INSERT INTO firstTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Connected','2017-06-27 10:17:56.330','2017-06-27 10:17:57.430',1);
INSERT INTO firstTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Connected','2017-06-27 10:17:57.430','2017-06-27 10:17:57.440',0);
INSERT INTO firstTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Connected','2017-06-27 10:17:57.440','2017-06-27 10:17:58.637',1);
INSERT INTO firstTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Connected','2017-06-27 10:17:58.637','2017-06-27 10:17:58.783',0);
INSERT INTO firstTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Connected','2017-06-27 10:17:58.783','2017-06-27 10:17:59.657',1);
INSERT INTO firstTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Connected','2017-06-27 10:17:59.657','2017-06-27 10:17:59.903',0);
INSERT INTO firstTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Connected','2017-06-27 10:17:59.903','2017-06-27 10:18:00.977',1);
INSERT INTO firstTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Connected','2017-06-27 10:18:00.977','2017-06-27 10:18:01.027',1);
INSERT INTO firstTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Connected','2017-06-27 10:18:01.027','2017-06-27 10:18:01.517',0);
Second table script:
CREATE TABLE secondTable(
DeviceId INTEGER NOT NULL
,Date DATE NOT NULL
,DisplayValue VARCHAR(16) NOT NULL
,LeftLimit DATETIME NOT NULL
,RigthLimit DATETIME NOT NULL
,Seconds INTEGER NOT NULL
);
INSERT INTO secondTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Mains - Charging','2017-06-27 00:00:00.000','2017-06-27 10:17:57.523',37077);
INSERT INTO secondTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Mains - Charging','2017-06-27 10:17:57.523','2017-06-27 10:17:59.883',2);
INSERT INTO secondTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Mains - Charging','2017-06-27 10:17:59.883','2017-06-27 10:17:59.953',0);
INSERT INTO secondTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Mains - Charging','2017-06-27 10:17:59.953','2017-06-27 10:18:01.043',2);
INSERT INTO secondTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Mains - Charging','2017-06-27 10:18:01.043','2017-06-27 10:18:01.103',0);
INSERT INTO secondTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Mains - Charging','2017-06-27 10:18:01.103','2017-06-27 10:18:01.553',0);
INSERT INTO secondTable(DeviceId,Date,DisplayValue,LeftLimit,RigthLimit,Seconds) VALUES (43,'2017-06-27','Mains - Charging','2017-06-27 10:18:01.553','2017-06-27 10:18:01.630',0);
Expected Result:
CREATE TABLE expectedResult(
DeviceId INTEGER NOT NULL
,LeftLimit DATETIME NOT NULL
,RigthLimit DATETIME NOT NULL
,TotalSeconds INTEGER NOT NULL
);
INSERT INTO expectedResult(DeviceId,LeftLimit,RigthLimit,TotalSeconds) VALUES (43,'2017-06-27 00:00:00.000','2017-06-27 10:18:02.630',37081);
Expected Result table:
+----------+-------------------------+-------------------------+--------------+
| DeviceId | LeftLimit | RightLimit | TotalSeconds |
+----------+-------------------------+-------------------------+--------------+
| 43 | 2017-06-27 00:00:00.000 | 2017-06-27 10:18:02.630 | 37081 |
+----------+-------------------------+-------------------------+--------------+
Upvotes: 1
Views: 886
Reputation: 180
SELECT DISTINCT
ST.[DeviceId],
MIN(CASE WHEN FT.[LeftLimit] > ST.[LeftLimit] THEN FT.[LeftLimit] ELSE ST.[LeftLimit] END) AS [LeftLimit],
MAX(CASE WHEN FT.[RigthLimit] < ST.[RigthLimit] THEN FT.[RigthLimit] ELSE ST.[RigthLimit] END) AS [RigthLimit],
SUM(DATEDIFF(
SECOND,
CASE WHEN FT.[LeftLimit] > ST.[LeftLimit] THEN FT.[LeftLimit] ELSE ST.[LeftLimit] END,
CASE WHEN FT.[RigthLimit] < ST.[RigthLimit] THEN FT.[RigthLimit] ELSE ST.[RigthLimit] END)) AS [TotalSeconds]
FROM firstTable FT
INNER JOIN secondTable ST ON ST.[DeviceId] = FT.[DeviceId] AND (FT.[LeftLimit] <= ST.[RigthLimit] AND ST.[LeftLimit] <= FT.[RigthLimit])
GROUP BY ST.[DeviceId]
Join the first table on the second, but only where the date ranges overlap. Then take the min left and max right limit and sum.
Upvotes: 1
Reputation: 31785
JOIN the two tables ON the LeftLimit
from the 2nd table being greater than the MIN LeftLimit
from the 1st table, AND the RightLimit
from the 2nd table being less than the MAX RightLimit
from the 1st table. And also on DeviceId
of course.
You'll also need to CAST all your limit columns as datetimes so that they compare correctly.
Upvotes: 0