簡體   English   中英

如何在SQL Server中使用rownumber獲取匹配數據?

[英]How to get matching data using rownumber in SQL Server?

我是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非常復雜。 必須有簡單的方法來獲得我想要的東西。 如果您有新方法,請隨時發布。 如果您有任何要添加到我現有查詢的內容,請隨時發布。 如果有困惑,請隨意評論。

如果您order by DateTimeStamp desc修改ROW_NUMBER() PARTITION以進行order by DateTimeStamp desc ,那么每個tkid的最新行將被賦予rn=1 ,從而為您提供每個tkid的最新狀態。 然后你只需要SELECT rn = 1Status = '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

有很多方法可以做到這一點,其中之一是:

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值可能具有更新的時間戳。

我想這可以顯示你的結果:

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))

但我在等待最好的答案;)。

這個怎么樣:

;with cte as 
(
    select *
         , MAX(DateTimeStamp) OVER (PARTITION BY tkid) AS maxDt
    from Prog_Timer
)
SELECT * 
FROM cte
WHERE DateTimeStamp=maxDt and Status='Start'

試試這個查詢:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM