[英]How to get matching data using rownumber in SQL Server?
I am new to SQL Server and I don't know how to word this question. 我是SQL Server的新手,我不知道怎么说这个问题。 I have feeling this might be repeated.
我觉得这可能会重演。 If you know it please flag it as duplicate.
如果您知道,请将其标记为重复。 I will explain with data what I am trying to achieve
我将用数据解释我想要实现的目标
Table data - sometable
表数据-
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
Expected output: 预期产量:
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
So basically I want to get the record which has the start
status but doesn't have the stop
status. 所以基本上我想获得具有
start
状态但没有stop
状态的记录。
Now What I tried .. 现在我尝试了什么..
I tried to use the ROW_NUMBER
function as below, 我尝试使用
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
It gives me result as 它给了我结果
And then try to get the tkid with the Odd
count and for that tkid got the data. 然后尝试使用
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
I don't know how to get the last row only from this output for each tkid
select only the last start row. 我不知道如何从每个
tkid
这个输出中获取最后一行只选择最后一个开始行。 I think my approch is pretty complicated. 我认为我的approch非常复杂。 There has to be simple way to get what I want.
必须有简单的方法来获得我想要的东西。 If you have new approach feel free to post.
如果您有新方法,请随时发布。 If you have anything to add to my existing query feel free to post.
如果您有任何要添加到我现有查询的内容,请随时发布。 In case of confusion feel free to comment.
如果有困惑,请随意评论。
If you modify your ROW_NUMBER() PARTITION
to order by DateTimeStamp desc
, then the latest row for each tkid
will be given rn=1
, thus giving you the latest status for each tkid
. 如果您
order by DateTimeStamp desc
修改ROW_NUMBER() PARTITION
以进行order by DateTimeStamp desc
,那么每个tkid
的最新行将被赋予rn=1
,从而为您提供每个tkid
的最新状态。 You then simply have to SELECT
rows where the rn = 1
and the Status = 'Start'
to get your desired output: 然后你只需要
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
Lot of ways to do this, one of them is below: 有很多方法可以做到这一点,其中之一是:
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'
Depending on the actual data, you might want to get MAX(ID) instead, in case it's sometimes possible for a process to stop and start at the same time. 根据实际数据,您可能希望获得MAX(ID),以防有时进程可以停止并同时启动。 But of course, in case of updates it could be possible for older ID values to have newer timestamps.
但是,当然,在更新的情况下,旧ID值可能具有更新的时间戳。
I think this can show your results: 我想这可以显示你的结果:
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))
But I'm waiting for best answer ;). 但我在等待最好的答案;)。
how about this: 这个怎么样:
;with cte as
(
select *
, MAX(DateTimeStamp) OVER (PARTITION BY tkid) AS maxDt
from Prog_Timer
)
SELECT *
FROM cte
WHERE DateTimeStamp=maxDt and Status='Start'
Try this query: 试试这个查询:
SELECT *
FROM tableName
WHERE Status = 'start'
AND ID NOT IN (SELECT ID
FROM tableName
WHERE Status = 'stop')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.