我的架构看起来像这样:
------------------------------------
ID | Time | Type | Description | obj
------------------------------------
有些数据会像
1 | 01/01/1900 01:01:01 AM | 1 | Start | O1
2 | 01/01/1900 01:01:02 AM | 1 | Start | O2
3 | 01/01/1900 01:01:03 AM | 2 | Stop | O1
4 | 01/01/1900 01:01:04 AM | 2 | Stop | O2
注意:
所以,我需要的是彼此最接近的开始时间和停止时间对。换句话说:对于每个开始时间,我需要下一个最接近的停止时间。因此,上面的示例数据的select语句的结果(仅选择的id)将返回:
(1,3)
(2,4)
我尝试了什么:
SELECT obj,
[Time] AS StartTime,
(SELECT MIN([TIME]) AS t
FROM TheTable
WHERE [Type] = 2
HAVING MIN([Time]) > StartTime) AS StopTime
FROM TheTable
WHERE [Type] = 1;
这显然不起作用,因为内部选择未知StartTime。 如果没有内部选择中的Having子句,它会运行但我会为所有条目获得相同的StopTime,正如您所期望的那样。当然,这不是我需要的。
有什么方法可以解决这个问题吗?
答案 0 :(得分:2)
SELECT t1.obj, t1.Time as Start, min(t2.Time) as Stop
FROM TheTable t1
LEFT OUTER JOIN TheTable t2
ON t1.obj = t2.obj and t2.Description = 'Stop' and t2.Time > t1.time
WHERE t1.Description = 'Start'
GROUP BY (t1.obj, t1.Time, t1.Description, t2.Description)
左外连接,因为可能有一个开始时间而不是停止时间
答案 1 :(得分:1)
我不确定为什么它不起作用。
你总是可以在SubQ中使用外部列引用,你缺少'逗号'和'分组'BTW
SELECT obj,
[Time] AS StartTime,
(SELECT MIN([TIME]) AS t
FROM TheTable
WHERE [Type] = 2
and t1.obj = obj
HAVING t > StartTime) AS StopTime
FROM TheTable t1
WHERE [Type] = 1
group by obj,TIME;
编辑:
我不是SQL服务器的专家,也不知道为什么列别名不起作用。此查询适用于我正在使用的其他Dbs,如Teradata。无论如何,您可以使用表别名来解决此问题。
SELECT obj,
[TIME] AS StartTime,
(SELECT MIN([TIME]) As [tt]
FROM TheTable
WHERE [Type] = 2
and t1.obj = obj
HAVING MIN([TIME]) > t1.TIME
) AS StopTime
FROM TheTable t1
WHERE [Type] = 1
group by obj,TIME;
SQLFiddle:
http://sqlfiddle.com/#!6/3a745/14
现在,似乎SQL服务器中的Having子句中不允许使用列别名:
SELECT obj,
min([tdate]) AS StartTime from thetable group by obj having starttime>5 ;
无效的列名'starttime'。:SELECT obj,min([tdate])来自thetable group的AS StartTime by obj having starttime> 5