我是SQL Server的新手,我不知道如何说出这个问题。我觉得这可能会重演。如果您知道,请将其标记为重复。我将用数据解释我想要实现的目标
表格数据 - sometable
ID TKID Status DateTimeStamp RunMin
-----------------------------------------------------
215 6 Start 2009-10-29 09:48:14.243 NULL
261 6 Stop 2009-10-30 10:05:16.460 1457
356 6 Start 2009-11-03 14:11:05.097 NULL
357 6 Stop 2009-11-03 15:20:05.133 1526
358 6 Start 2009-11-03 16:14:45.863 NULL
574 19 Start 2009-11-12 13:12:11.827 NULL
575 19 Stop 2009-11-12 13:47:23.077 35
543 259 Start 2009-11-12 09:01:24.013 NULL
620 259 Stop 2009-11-14 11:25:30.177 NULL
623 259 Start 2009-11-14 16:47:32.913 NULL
720 352 Start 2009-11-18 17:47:38.637 NULL
730 352 Stop 2009-11-19 08:22:28.317 874
773 352 Start 2009-11-20 10:00:11.320 NULL
778 352 Stop 2009-11-20 11:51:59.853 985
812 352 Start 2009-11-20 17:51:35.640 NULL
813 352 Stop 2009-11-20 17:53:52.373 987
822 352 Start 2009-11-23 08:13:23.030 NULL
823 352 Stop 2009-11-23 08:17:33.063 991
901 352 Start 2009-12-01 10:50:16.547 NULL
910 352 Stop 2009-12-01 10:50:54.200 991
预期产出:
ID TKID Status DateTimeStamp RunMin
-----------------------------------------------------
358 6 Start 2009-11-03 16:14:45.863 NULL
623 259 Start 2009-11-14 16:47:32.913 NULL
所以基本上我想获得具有start
状态但没有stop
状态的记录。
现在我尝试了什么..
我尝试使用ROW_NUMBER
功能,如下所示
;with cte as
(
select
*,
ROW_NUMBER() OVER (PARTITION BY tkid
ORDER BY tkid, DateTimeStamp) AS rn
from Prog_Timer
)
SELECT *
FROM
(SELECT *
FROM cte
WHERE TkID IN (SELECT TkID
FROM cte
GROUP BY TkID
HAVING COUNT(*)% 2 = 1)
) as d
它给我结果
然后尝试使用Odd
计数得到tkid,并且tkid得到了数据。
ID TKID Status DateTimeStamp RunMin
-----------------------------------------------------
215 6 Start 2009-10-29 09:48:14.243 NULL
261 6 Stop 2009-10-30 10:05:16.460 1457
356 6 Start 2009-11-03 14:11:05.097 NULL
357 6 Stop 2009-11-03 15:20:05.133 1526
358 6 Start 2009-11-03 16:14:45.863 NULL
543 259 Start 2009-11-12 09:01:24.013 NULL
620 259 Stop 2009-11-14 11:25:30.177 NULL
623 259 Start 2009-11-14 16:47:32.913 NULL
我不知道如何从每个tkid
的此输出中获取最后一行仅选择最后一个开始行。我认为我的approch非常复杂。必须有简单的方法来获得我想要的东西。如果您有新方法,请随时发布。如果您有任何要添加到我现有查询的内容,请随时发布。如果有困惑,请随时发表评论。
答案 0 :(得分:5)
如果您将ROW_NUMBER() PARTITION
修改为order by DateTimeStamp desc
,则每个tkid
的最新行将被rn=1
,从而为您提供每个tkid
的最新状态}}。然后,您只需SELECT
行rn = 1
和Status = 'Start'
即可获得所需的输出:
select * from
(select
*,
ROW_NUMBER() OVER (PARTITION BY tkid order by DateTimeStamp desc) as rn
from Prog_Timer
)
T
where
T.rn = 1 -- the latest status for each tkid
and T.Status = 'Start' -- returns only started and not stopped timers
-- if timer is stopped, t.Status will be 'Stop' in the latest row
答案 1 :(得分:1)
很多方法可以做到这一点,其中一个方法如下:
SELECT T.*
FROM SOMETABLE T
JOIN (SELECT MAX(DATETIMESTAMP) MAXTIME, TKID
FROM SOMETABLE
GROUP BY TKID) SRC
ON SRC.MAXTIME = T.DATETIMESTAMP AND SRC.TKID = T.TKID
WHERE T.STATUS = 'Start'
根据实际数据,您可能希望获得MAX(ID),以防有时可以让进程停止并同时启动。但是,当然,如果更新,旧ID值可能会有更新的时间戳。
答案 2 :(得分:1)
我认为这可以显示您的结果:
select *
from Prog_Timer st
where st.[Status] = 'Start' And
isnull((select min(sti.DateTimeStamp) from Prog_Timer sti
where sti.[Status] = 'Stop' And sti.TKId = st.TKId And sti.DateTimeStamp > st.DateTimeStamp )
, cast('2999/12/29' as datetime))
>
isnull((select min(stii.LogDateTime) from Prog_Timer stii
where stii.[Status] = 'Start' And stii.TKId = st.TKId And stii.DateTimeStamp > st.DateTimeStamp)
, cast('2999/12/29' as datetime))
但我等着最好的答案;)。
答案 3 :(得分:0)
怎么样:
;with cte as
(
select *
, MAX(DateTimeStamp) OVER (PARTITION BY tkid) AS maxDt
from Prog_Timer
)
SELECT *
FROM cte
WHERE DateTimeStamp=maxDt and Status='Start'
答案 4 :(得分:-3)
尝试此查询:
SELECT *
FROM tableName
WHERE Status = 'start'
AND ID NOT IN (SELECT ID
FROM tableName
WHERE Status = 'stop')