【问题标题】:TSQL - LEAD for Next Different RowTSQL - 下一个不同行的 LEAD
【发布时间】:2015-02-25 10:56:58
【问题描述】:

有没有一种方法可以使用前导函数,这样我就可以获得发生变化的下一行,而不是相同的地方?

在这个例子中,RowType 可以是“in”或“out”,对于每个“in”,我需要知道它变成“out”的下一个 RowNumber。我一直在玩主角功能,因为它真的很快,但是我无法让它工作。我只需要真正执行以下操作,即按不是当前行中的 RowType 进行分区。

select
RowNumber
,RowType --In this case I am only interested in RowType = 'In'
, Lead(RowNumber) 
    OVER (partition by "RowType = out" --This is the bit I am stuck on--
          order by  RowNumber ASC) as NextOutFlow
from table
order by RowNumber asc 

提前感谢您的帮助

【问题讨论】:

    标签: tsql analytic-functions


    【解决方案1】:

    我会使用outer apply,而不是使用outer apply,它为所有in类型的行返回out类型的下一行:

    select RowNumber, RowType, nextOut 
    from your_table t
    outer apply (
      select min(RowNumber) as nextOut 
      from your_table 
      where RowNumber > t.RowNumber and RowType='Out'
    ) oa
    where RowType = 'In'
    order by RowNumber asc 
    

    给定示例数据,例如:

    RowNumber   RowType
    1           in
    2           out
    3           in
    4           in
    5           out
    6           in
    

    这将返回:

    RowNumber   RowType nextOut
    1           in      2
    3           in      5
    4           in      5
    6           in      NULL
    

    【讨论】:

    • 使用外部应用该过程大约需要 2 个小时,而如果可以使前导功能起作用,它可能只需要几秒钟(使用前导来获取下一行目前在我的数据集)
    • @SomeGuy30145 我没想到外部应用会花那么长时间 - 请问您正在使用的数据集有多大?我想不出一种方法来使用lead() 来做到这一点,虽然也许这是可能的。
    • 大约 200 万行
    • @SomeGuy30145 我对查询做了一个小改动,在我对一百万行随机输入/输出值的测试中,查询现在在 4 秒内完成。我也为rownumber,rowtype 设置了一个支持索引,但这不应该提高性能。请立即尝试,看看它的执行速度是否足够快。
    • @VladimirBaranov - 谢谢 - 将表拆分为 2 个,一个用于流入,一个用于流出,然后在每个新表上应用索引,然后将它们一起应用到外部,这是一个非常有效的查询 - thw整个 ETL 需要 2 分钟 30 分钟,而最后一部分需要 8 小时。谢谢!
    【解决方案2】:

    我认为这会起作用
    如果您将位字段用于 in out,您将获得更好的性能

    ;with cte1 as 
    (
      SELECT [inden], [OnOff]
           , lag([OnOff]) over (order by [inden]) as [lagOnOff]
        FROM [OnOff] 
    ),   cte2 as
    (
      select [inden], [OnOff], [lagOnOff]
           , lead([inden]) over (order by [inden]) as [Leadinden]
        from cte1 
       where [OnOff] <> [lagOnOff]
          or [lagOnOff] is null
     )
     select [inden], [OnOff], [lagOnOff], [Leadinden]
       from cte2 
      where [OnOff] = 'true'
    

    可能会更慢,但如果你有正确的索引可能会起作用

    select t1.rowNum as 'rowNumIn', min(t2.rownum) as 'nextRowNumOut' 
      from tabel t1 
      join table t2 
        on t1.rowType = 'In' 
       and t2.rowType = 'Out'
       and t2.rowNum > t1.rowNum  
       and t2.rowNum < t1.rowNum + 1000  -- if you can constrain it 
     group by t1.rowNum
    

    【讨论】:

    • 第一个运行速度非常快,就像比仅仅调用表还要快,这太棒了。但是,它只获取 'In' 的第一个实例,然后是后续的 'out' ,如果有连续的 'in' - 它们都应该得到相同的 'out' - 另一个建议的输出显示了这一点。我将 inout 字段更改为有点像你建议的那样。
    • 哎哟。如果您需要跳多行,那么为什么您认为领先/滞后是正确的方法?
    • 我根本不知道这是否是正确的方法,但如果它有效,它可能会非常快。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多