【问题标题】:How do I calculate a median-to-date variable using Oracle SQL?如何使用 Oracle SQL 计算当前变量的中位数?
【发布时间】:2011-11-05 09:49:31
【问题描述】:

我正在使用 Oracle SQL 中的发票数据。我想创建一个变量“迄今为止的中位数帐户发票金额”,它给出了截至给定发票日期的帐户发票金额中位数。

【问题讨论】:

    标签: sql oracle time-series analytic-functions


    【解决方案1】:

    Oracle 实际上有一个median 函数。要查找每天所有帐户的中位数:

    select  median(amount)
    from    invoices
    

    或显示每个帐户每天的中位数:

    select  AccountNr
    ,       to_char(InvoiceDate, 'yyyymmdd')
    ,       median(amount)
    from    invoices
    group by
            AccountNr
    ,       to_char(InvoiceDate, 'yyyymmdd')
    

    或显示“运行中位数”:

    select  i1.custID
    ,       i1.inv_date
    ,       median(i2.amount)
    from    invoices i1
    join    invoices i2
    on      i2.custId = i1.custID
            and i2.inv_date <= i1.inv_date
    group by
            i1.custID
    ,       i1.inv_date
    

    【讨论】:

    • 谢谢。不完全是我所追求的。对于每个帐户和每个日期,发票金额的中位数是多少?
    • Median(amount) 将是当天的金额。前一天所有金额的中位数是多少?即迄今为止的中位数?这可以使用分析函数来实现,例如,平均至今? avg(inv_amount) over (partition by supertest.custID order by inv_date 但是替换中位数会出错
    • @OracleQuery:奇怪,看起来median 不支持像avg 那样的运行总和。编辑答案以使用自连接计算中位数。
    • 有什么方法可以使用分析函数而不是连接来实现这一点...为了提高效率
    • @Ben:是的,但与avg 不同,median 不允许使用order by 子句,因此您不能将其用于运行中位数
    【解决方案2】:

    据我了解,这就是您所追求的。 @Andomar,因为中位数是一系列数字的中间,所以这个系列对结果没有影响。最高和最低之间的中间数字不能改变...

    因此,按数据和帐户计算的中位数为:

    select acc_no, median(amount) over ( partition by acc_no, to_char(invoice_date,'yyyymmdd'))
      from invoices
           -- if applicable
     where invoice_date < :date
    

    按帐户计算的中位数是

    select acc_no, median(amount) over ( partition by acc_no )
     from invoices
    where invoice_date < :date
    

    【讨论】:

    • 订购该系列对于平均值也无关紧要。 avg() over (order by...) 的 order by 是它计算当前值之前所有值的运行平均值。
    • @Andomar,感谢您的澄清。我知道这非常有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多