2017-10-09 50 views
3

我有以下幾點:消除行

Index dateOfInquiry 
649454  2016-02-05 
649455  2016-02-05 

而且我有此查詢:

SELECT COUNT(a.dateOfInquiry) as NumberRecords 
FROM 
( 
    SELECT ROW_NUMBER() OVER(ORDER BY dateOfInquiry ASC) 
     Id, dateOfInquiry 

    FROM 
    Table 
) a 

INNER JOIN 
(
    SELECT ROW_NUMBER() OVER(ORDER BY dateOfInquiry ASC) 
      Id, dateOfInquiry 

    FROM 
     Table 
) 
b 

ON b.ID = a.ID + 1 
WHERE ABS(DATEDIFF(d, a.dateOfInquiry, b.dateOfInquiry)) > 14 
GROUP BY a.strTransactionID 

我試圖做的僅僅是每7天退貨1項紀錄他們存在的時期。所以我想要1在上面的數據集中,但我得到0(它消除了兩個記錄,因爲它們之間沒有14天)

而且,如果有更多記錄並且行爲不是'很正確。如果我在1日,2日,3日等到15日有記錄,我仍然只需要1條記錄,然後在16日或以後的下一條記錄再次開始計數,忽略其他記錄,直到差異爲止超過14天。

基本上我想把一個記錄計爲1,然後忽略所有進一步的記錄,直到14天結束。

我想另一個樣品,結果是2:

Index dateOfInquiry 
649454  2016-02-01 <- count 
649455  2016-02-12 -ignore (<l4 past 649454) 
649456  2016-02-12 -ignore (<l4 past 649454) 
649457  2016-02-17 <- count 
649458  2016-02-22 -ignore (<l4 past 649457) 
649459  2016-02-25 -ignore (<l4 past 649457) 

回答

1

使用outer apply()獲得下一個符合條件的行的每一行的id,並使用遞歸common table expression在開始和工作啓動前進的路:

;with cte as (
    select t.id, t.dateOfInquiry, x.next_id 
    from t 
    outer apply (
     select top 1 next_id = i.id 
     from t as i 
     where i.dateOfInquiry > dateadd(day,14,t.dateOfInquiry) 
     order by dateofInquiry, id asc 
    ) x 
) 
, r_cte as (
    --anchor row(s)/starting row(s) 
    select 
     id 
    , dateOfInquiry 
    , next_id 
    from cte t 
    where not exists (
    select 1 
    from cte as i 
    where i.id < t.id 
    ) 
    union all 
    --recursion starts here 
    select 
     c.id 
    , c.dateOfInquiry 
    , c.next_id 
    from cte c 
    inner join r_cte p 
     on c.id = p.next_id 
) 
select id, dateOfInquiry 
from r_cte 

rextester演示:http://rextester.com/PIMVPM32168

回報:

+--------+---------------+ 
| id | dateOfInquiry | 
+--------+---------------+ 
| 649454 | 2016-02-01 | 
| 649457 | 2016-02-17 | 
+--------+---------------+ 
+0

謝謝,我今天早上要試試這個。如果我想從中看出來,我可以將「With」表作爲視圖,並用視圖替換cte的實例,對吧? –

+0

@PatrickSchomburg是的,只要將'with'移到'r_cte之前('。像這樣:http://rextester.com/PLNO30199 – SqlZim

1
what is the use of index column in you requirement ? 

你應該提供真正喜歡的場景。

嘗試我的腳本與其他示例data.I使用2 ROW_NUMBER函數遞歸CTE.So假設如果沒有比這更好的解決方案出現,那麼我認爲CURSOR將是一個更好的和可以理解的方法。

declare @t table(Index1 int,dateOfInquiry datetime) 
insert into @t VALUES 
(649454,'2016-02-01') --<- count 
,(649455,'2016-02-12') ---ignore (<l4 past 649454) 
,(649456,'2016-02-12') ---ignore (<l4 past 649454) 
,(649457,'2016-02-17') --<- count 
,(649458,'2016-02-22') ---ignore (<l4 past 649457) 
,(649459,'2016-03-02') ---count 
,(649459,'2016-03-15') ---ignore (<l4 past 649457) 

;WITH CTE 
AS (
    SELECT min(dateOfInquiry) dateOfInquiry 
     ,cast(0 AS BIGINT) r 
    FROM @t 

    UNION ALL 

    SELECT * 
    FROM (
     SELECT t.dateOfInquiry 
      ,ROW_NUMBER() OVER (
       ORDER BY t.dateOfInquiry 
       ) rn1 
     FROM @t t 
     INNER JOIN (
      SELECT dateOfInquiry 
      FROM (
       SELECT dateOfInquiry 
        ,row_number() OVER (
         ORDER BY dateOfInquiry DESC 
         ) rn 
       FROM cte c1 
       ) c2 
      WHERE rn = 1 
      ) c1 ON datediff(day, c1.dateOfInquiry, t.dateOfInquiry) >= 14 
     ) t4 
    WHERE rn1 = 1 
    ) 
SELECT * 
FROM cte