SQL使用lag和lead缩小查询结果的范围

时间:2015-03-02 18:13:44

标签: sql-server sql-server-2012

我正在使用滞后写一个查询,并导致回顾并获得一个人之前的活动,当前活动和下一个活动。不幸的是,如后所述,结果并不正确。我需要它来显示当前值,在它之前的new_activity_code(前一个值)以及下一个将发生的活动代码(nextvalue)。

我需要它才能显示当前活动和前面提到的项目。我需要它为多个债务人工作,而不是同一个债务人的多个条目。

示例表:

表invoice_activity:

Invoice_id    debtorId      New_activity_Code           Next_activity_date
  456         00001            123456                           1/2/2015
  741         00002            123456                           2/2/2015
  147         00002            789123                           2/16/2015
  258         00003            987321                           2/24/2015
  369         00004            852369                           2/23/2015
  753         00002            753357                           3/16/2015
  951         00003            428619                           3/24/2015
  428         00004            951628                           3/23/2015
  852         00003            123456                           3/24/2015
  963         00004            123456                           4/11/2015
  654         00001            456789                           5/8/2015

示例输出:

Debtor ID       PreviousValue     CurrentValue      NextValue     Next_act_date
00001               123456           456789           NULL           5/8/2015
00002               123456           789123           753357         3/16/2015
00003               123456           987321           428619         3/24/2015
00004               123456           852369           951628         3/23/2015

我似乎得到的似乎是输出,但每张新发票都会重复。

查询:

SELECT
    distinct
    debtor_id,
    LAG(ia.new_activity_code) OVER (partition by debtor_id ORDER BY debtor_id) PreviousValue, 
    ia.new_activity_code,
    max(next_activity_date) as next_act_date
FROM
    invoice_activity ia 
WHERE
    debtor_id IN
        (SELECT
             distinct debtor_id
         FROM
             debtor
         WHERE
             client_id=1234)
GROUP BY
    debtor_id,
    new_activity_code
ORDER BY
    next_act_date

1 个答案:

答案 0 :(得分:0)

不确定您实际期望的结果是,每个债务人的下一个发生的那个(例如最小但未来)?我认为这会回归:

select
  debtor_id, 
  previous_value,
  new_activity_code,
  Next_Value,
  next_activity_date
from (
  select
    debtor_id,
    previous_value,
    new_activity_code,
    Next_Value,
    next_activity_date,
    row_number() over (partition by debtor_id 
        order by next_activity_date asc) as rn
  from(
    SELECT
        debtor_id,
        LEAD(ia.new_activity_code) OVER (partition by debtor_id 
            ORDER BY Next_activity_date desc) Previous_Value, 
        LAG(ia.new_activity_code) OVER (partition by debtor_id 
            ORDER BY Next_activity_date desc) Next_Value, 
        ia.new_activity_code,
        Next_activity_date
    FROM
        invoice_activity ia 
  ) t
  where
    next_activity_date > getdate()
 ) t
where rn = 1

一个问题是数据中存在重复记录,或者至少我不确定应该如何处理这个记录,因为它是同一个债务人和同一个日期:

951         00003            428619                           3/24/2015
852         00003            123456                           3/24/2015

至少如果我的分析是正确的,对于债务人2来说,这应该是正确答案:

753         00002            753357                           3/16/2015

而不是这个(找到前一个值):

147         00002            789123                           2/16/2015

对于SQL,最里面的select获取每个行+它的下一个值(按日期降序),然后在它之外的那个以相反的顺序(日期升序)为行分配行号以获得一个最接近当前日期+过滤掉过去的行,最外面的选择只获得rn = 1的行。