簡體   English   中英

檢查更改歷史記錄中連續y個月的值是否大於x

[英]Check if value was greater than x for y consecutive months period in changes history

我有成員級別更改的表。 它具有所有成員級別的歷史變化以及發生變化時的日期。 例如,我可以列出會員編號5的更改:

select * from memberlevelhistory where member = 5

結果:

member  changedate  level
5       2012-04-01  2
5       2012-03-01  3
5       2012-02-01  2
5       2011-02-01  6
5       2011-02-01  6
5       2010-03-15  6
5       2010-02-01  5
5       2010-01-01  5
5       2009-10-01  4
5       2009-08-27  2
5       2009-08-01  1

歷史表中的最后一個條目是當前級別。

問題:如何列出3個月或更長時間內水平高於或等於3的所有成員?

這是問題的簡化版本。 為了讓它變得更有趣,我只需要在這3個月期間內沒有低於起始水平的成員。 因此,如果一個成員在4個月期間開始了4級並且在上個月只是3級,那么該成員將被排除在列表之外。

任何幫助,即使是簡化的問題,我們都非常感謝。

擴大的視野:

我還需要在最近6個月的窗口內發生> = 3個月的水平> = 3的時期。

這可能是not exists的情況。 如果在接下來的三個月內沒有其他條目的級別低於當前選定的記錄,則條目有效。 這解決了這兩個要求。 每個成員的最后一個條目可能存在問題,其中級別適當,但跨度未知。 我已決定刪除這些記錄,但您可能還有其他想法。

Sql Fiddle with example就在這里

select distinct mlh.member
  from memberlevelhistory mlh
 where mlh.level >= 3
   and not exists
       (
         select null
           from memberlevelhistory mlh2
          where mlh2.member = mlh.member
            and mlh2.changedate >= mlh.changedate
            and mlh2.changedate < dateadd(month, 3, mlh.changedate)
            and mlh2.level < mlh.level
       )
    -- The last entry might have appropriate level
    -- But we cannot tell how long it lasted,
    -- So we are going to remove it.
   and exists
       (
         select null
           from memberlevelhistory mlh3
          where mlh3.member = mlh.member
            and mlh3.changedate > mlh.changedate
       )

編輯:

我已經重寫了不存在()到左連接並添加了“持續到今天的最后一個條目”標准。

Sql Fiddle with example就在這里。

select distinct mlh.member
  from memberlevelhistory mlh
  left join memberlevelhistory mlh2
    on mlh2.member = mlh.member
   and mlh2.changedate >= mlh.changedate
   and mlh2.changedate < dateadd(month, 3, mlh.changedate)
   and mlh2.level < mlh.level
 where mlh.level >= 3
   and mlh2.member is null
   and datediff(month, mlh.changedate, getdate()) >= 3

查詢重寫:

; with ranges as 
(
  select mlh.member, mlh.changedate StartRange, min(isnull(mlh2.changedate, getdate())) EndDate
    from memberlevelhistory mlh
    left join memberlevelhistory mlh2
      on mlh2.member = mlh.member
     and mlh2.changedate >= mlh.changedate
     and mlh2.level < mlh.level
   where mlh.level >= 3
  group by mlh.member, mlh.changedate
 having datediff (month, min(isnull(mlh2.changedate, getdate())), getdate()) <= 6
    and datediff (month, mlh.changedate, min(isnull(mlh2.changedate, getdate()))) >= 3
)
select distinct member
  from ranges

而Sql Fiddle就在這里

我認為100和101應該被包括在內,因為它們都有3個月的良好運行,並且這是在3月之前的六個月之前。

我所做的是在有人跑得好的時候生成范圍,然后在3個月或更長的時間內測試這個范圍,在過去六個月中測試結束日期。

更新 :如果我終於得到了它的權利,你需要的是持續時間在過去的六個月為期三個月。 計算可能會將更改截斷為當前日期 - 六個月。 使用它作為起始點,並且找到范圍的結束點作為具有較低級別和較高日期作為結束點的第一mlh具有足夠的信息來計算持續時間。

; with ranges as 
(
  select mlh.member, 
  -- If good range starts more than six months before today
  -- truncate it to today - 6 months
         case when datediff (month, mlh.changedate, getdate()) > 6
              then dateadd(month, -6, getdate())
              else mlh.changedate 
              end StartRange,
  -- First bad mlh after current changedate
         min(isnull(mlh2.changedate, getdate())) EndRange
    from memberlevelhistory mlh
    left join memberlevelhistory mlh2
      on mlh2.member = mlh.member
     and mlh2.changedate >= mlh.changedate
     and mlh2.level < mlh.level
   where mlh.level >= 3
  group by mlh.member, mlh.changedate
  -- As above, limit good range to max six months before today
  -- And only get those lasting at least three months
 having datediff (month, case when datediff(month, mlh.changedate, getdate()) > 6
                              then dateadd(month, -6, getdate())
                              else mlh.changedate 
                          end, 
                         min(isnull(mlh2.changedate, getdate()))) >= 3
)
select distinct member
  from ranges

Sql Fiddle with example就在這里

SELECT * FROM (
  SELECT MEMBER, CHANGEDATE, LEVEL, COUNT(LEVEL) AS COUNT
  FROM MEMBERLEVELHISTORY
  GROUP BY MEMBER, CHANGEDATE, LEVEL)
WHERE LEVEL >= 3
AND COUNT >= 3;

這應該對我們的簡化版本有幫助,但為了連續分組結果超出我的意義!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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