在SQL Server中,我有两个这样的查询结果:
我想使用这2个查询,然后使用第二个表(主要 - 计费)的SUM,如果特定设备(在这种情况下为43)在该时间段的第一个表的日期范围内连接使用左右日期限制。所以只有在满足条件的情况下才会使用SUM。
关于如何实现这一目标的任何建议?
这是表脚本和一些示例数据:
第一个表脚本:
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);
第二个表脚本:
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);
预期结果:
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);
预期结果表:
+----------+-------------------------+-------------------------+--------------+
| DeviceId | LeftLimit | RightLimit | TotalSeconds |
+----------+-------------------------+-------------------------+--------------+
| 43 | 2017-06-27 00:00:00.000 | 2017-06-27 10:18:02.630 | 37081 |
+----------+-------------------------+-------------------------+--------------+
答案 0 :(得分:1)
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]
在第二个表上加入第一个表,但仅限于日期范围重叠的位置。然后取最小左和右最大限制并求和。
答案 1 :(得分:0)
将来自第二个表的LeftLimit
上的两个表加入大于第一个表中的MIN LeftLimit
,并且来自第二个表的RightLimit
小于MAX { {1}}来自第一张表。当然还要RightLimit
。
您还需要将所有限制列作为日期时间进行CAST,以便正确比较。