【问题标题】:SQL Calculated Column based on OVER PARTITION BY Clause基于 OVER PARTITION BY 子句的 SQL 计算列
【发布时间】:2020-03-27 09:53:11
【问题描述】:

我有一个基于 PARTITION BY 跨某些列的 ROW NUMBER 视图。 ROW NUMBER 从 0 开始,并根据来自各种文件的 ssis 输入为每条记录递增, 对于每个具有唯一文件名和日期组合的文件,会有从 0 到 n 的行号。

现在我需要创建一个新列,使用行号对值进行计算。

RowNumber Value Filename FileDate  
0           500   datax   20200301  
1           200   datax   20200301  
2           100   datax   20200301  
0           600   datax   20200302  
1           200   datax   20200302  
2           200   datax   20200302  
3           100   datax   20200302  
4           200   datax   20200302  
0           700   datay   20200303  
1           500   datay   20200303 

我想要一个新列,将每个 RowNumber n 中的值除以 RowNumber 0 中的值,用于其唯一分区

NEWVALUE = (Value @ RowNumber N / Value at RowNumber 0)

RowNumber Value  NEWVALUE          Filename FileDate  
0           500   NULL             datax   20200301  
1           200   0.400            datax   20200301  
2           100   0.200            datax   20200301  
0           600   NULL             datax   20200302  
1           200   0.333            datax   20200302  
2           200   0.333            datax   20200302  
3           100   0.167            datax   20200302  
4           300   0.500            datax   20200302  
0           700   NULL             datay   20200303  
1           500   0.714            datay   20200303  

谁知道怎么做

【问题讨论】:

  • “跨一些列” - 哦,天哪,我们猜猜 - 是跨 FileDate 吗?我可以猜到ORDER BYValue 降序。尚不清楚Filename 是否相关,但如果您只是向我们展示了实际 ROW_NUMBER,这一切都会变得容易很多
  • 看看FIRST_VALUE
  • 作为@Larnu,建议您只需要一个窗口函数作为FIrST_VALUE。参考docs.microsoft.com/en-us/sql/t-sql/functions/…
  • @404,OP 不需要分区中的前一个值,而是第一个值。
  • FIRST_VALUE 成功了,谢谢@Gordon。

标签: sql tsql


【解决方案1】:

像其他人建议的那样,ROWNUM = 0 相当于 FIRST_VALUE

棘手的一点是为 NEWVALUE 添加一个 null 而不是 1,您将不得不求助于子查询。

SELECT 
RowNumber,Value,CASE WHEN RowNumber=0 THEN NULL else NEWVALUE end as NEWVALUE, FileName,FileDate
FROM (
  select ROW_NUMBER() OVER (PArtition BY FileDate ORDER BY Value DESC) -1 as RowNumber,
  Value,
  Value * 1.0 / FIRST_VALUE(Value) OVER (PArtition BY FileDate ORDER BY Value DESC) as NEWVALUE
  ,FileName
  ,FileDate
  from Data
  ) t

这里是 sqlfiddle 如果你想玩它http://sqlfiddle.com/#!18/2bdca4/1

【讨论】:

    【解决方案2】:

    一种方法使用条件聚合:

    select ( value * 1.0 /
             max(case when rownumber = 0 then value end) over (partition by filename, filedate)
             value
           ) as ratio
    

    我猜测分区组是基于filenamefilegroup

    或者使用first_value():

    select ( value * 1.0 /
             first_value(value) over (partition by filename, filedate order by rownumber)
             value
           ) as ratio
    

    要将其中任何一个放入视图中,您需要一个子查询。

    如果排序是基于最大值,那么你可以使用类似的逻辑(并且省去子查询):

    select ( value * 1.0 /
             max(value) over (partition by filename, filedate)  * 1.0
             value
           ) as ratio
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-04
      • 2019-03-21
      • 2021-12-15
      • 2021-12-01
      • 2017-11-02
      • 2018-09-01
      • 2014-03-10
      • 1970-01-01
      相关资源
      最近更新 更多