计算中位数移动平均单位成本时使用 Over(Partition By)

2024-03-03

早上好, 我正在尝试计算特定仓库中每件商品的 12 个月移动平均成本 (MAUC)。我正在使用 2012_B – 分页技巧来计算中位价格(http://sqlperformance.com/2012/08/t-sql-queries/median http://sqlperformance.com/2012/08/t-sql-queries/median)而不是使用 AVG 来消除异常值导致结果偏差的可能性。

以下代码有效,但它仅计算一项或所有项目的 MAUC - 取决于我是否删除或保留“AND t_item = 'xxxxx'


WITH Emily AS 

(SELECT 

 t_item AS [Item Code]
,t_mauc_1 AS [MAUC]

FROM twhina113100
WHERE t_cwar = '11'

AND t_item = '         TNC-C2050NP-G'

AND t_trdt > GETDATE()-365)


(SELECT 

AVG(1.0 * [Valuation Table].[MAUC])

FROM (
    SELECT [MAUC] FROM Emily
     ORDER BY [Emily].[MAUC]

     OFFSET ((SELECT COUNT(*) FROM Emily) - 1) / 2 ROWS
     FETCH NEXT 1 + (1 - (SELECT COUNT(*) FROM Emily) % 2) ROWS ONLY

)  AS [Valuation Table] )

我相信使用 Over(Partition By) 可能会帮助我按 t_item 进行分区,但是我不知道将其插入代码中的位置。我对 SQL 还很陌生,而且我缺乏正式培训的情况开始显现出来。

如果您还有其他建议请分享。

任何帮助将非常感激!


这个引起了我的注意,所以我发布了两个选项:

第一种是直接 cte 方法,第二种使用临时表。 cte 方法适用于较小的数据集,但随着系列的扩展,性能会受到影响。

这两个选项都会计算数据系列的 RUNNING Min、Max、Mean、Median 和 Mode

在我们开始讨论之前,先介绍几项。标准化结构是ID和Measure。
- ID 可以是日期或身份。
- 度量是任何数值 - 中位数是排序序列的中间值。如果观察次数为偶数,我们返回中间两条记录的平均值 - 模式表示为ModeR1 和ModeR2。如果没有重复值,我们将显示最小/最大范围

好的,让我们看一下 cte 方法

Declare @Table table (ID Int,Measure decimal(9,2))
Insert into @Table (ID,Measure) values
(1,25),
(2,75),
(3,50),
(4,25),
(5,12),
(6,66),
(7,45)

;with cteBase as (Select *,RowNr = Row_Number() over (Order By ID) From  @Table),
      cteExpd as (Select A.*,Measure2 = B.Measure,ExtRowNr = Row_Number() over (Partition By A.ID Order By B.Measure) From cteBase A Join cteBase B on (B.RowNr<=A.RowNr)),
      cteMean as (Select ID,Mean=Avg(Measure2),Rows=Count(*) From cteExpd Group By ID),
      cteMedn as (Select ID,MedRow1=ceiling(Rows/2.0),MedRow2=ceiling((Rows+1)/2.0) From cteMean),
      cteMode as (Select ID,Mode=Measure2,ModeHits=count(*),ModeRowNr=Row_Number() over (Partition By ID Order By Count(*) Desc) From cteExpd Group By ID,Measure2)
 Select A.ID
       ,A.Measure
       ,MinVal  = min(Measure2)
       ,MaxVal  = max(Measure2)
       ,Mean    = max(B.Mean)
       ,Median  = isnull(Avg(IIF(ExtRowNr between MedRow1 and MedRow2,Measure2,null)),A.Measure)
       ,ModeR1  = isnull(max(IIf(ModeHits>1,D.Mode,null)),min(Measure2))
       ,ModeR2  = isnull(max(IIf(ModeHits>1,D.Mode,null)),max(Measure2))
  From  cteExpd A
  Join  cteMean B on (A.ID=B.ID)
  Join  cteMedn C on (A.ID=C.ID)
  Join  cteMode D on (A.ID=D.ID and ModeRowNr=1)
  Group By A.ID
          ,A.Measure
  Order By A.ID

Returns

ID  Measure MinVal  MaxVal  Mean        Median      ModeR1  ModeR2
1   25.00   25.00   25.00   25.000000   25.000000   25.00   25.00
2   75.00   25.00   75.00   50.000000   50.000000   25.00   75.00
3   50.00   25.00   75.00   50.000000   50.000000   25.00   75.00
4   25.00   25.00   75.00   43.750000   37.500000   25.00   25.00
5   12.00   12.00   75.00   37.400000   25.000000   25.00   25.00
6   66.00   12.00   75.00   42.166666   37.500000   25.00   25.00
7   45.00   12.00   75.00   42.571428   45.000000   25.00   25.00

对于较小的数据系列,这种 cte 方法非常轻且快速

现在是临时表方法

-- Generate Base Data -- Key ID and Key Measure
Select ID     =TR_Date
      ,Measure=TR_Y10,RowNr = Row_Number() over (Order By TR_Date)
 Into  #Base
 From [Chinrus-Series].[dbo].[DS_Treasury_Rates] 
 Where Year(TR_Date)>=2013

-- Extend Base Data one-to-many
Select A.*,Measure2 = B.Measure,ExtRowNr = Row_Number() over (Partition By A.ID Order By B.Measure) into #Expd From #Base A Join #Base B on (B.RowNr<=A.RowNr) 
Create Index idx on #Expd (ID)

-- Generate Mean for Series
Select ID,Mean=Avg(Measure2),Rows=Count(*) into #Mean From #Expd Group By ID
Create Index idx on #Mean (ID)

-- Calculate Median Row Number(s)  -- If even(avg of middle two rows)
Select ID,MednRow1=ceiling(Rows/2.0),MednRow2=ceiling((Rows+1)/2.0) into #Medn From #Mean
Create Index idx on #Medn (ID)

-- Calculate Mode
Select * into #Mode from (Select ID,Mode=Measure2,ModeHits=count(*),ModeRowNr=Row_Number() over (Partition By ID Order By Count(*) Desc,Measure2 Desc) From #Expd Group By ID,Measure2) A where ModeRowNr=1
Create Index idx on #Mode (ID)

-- Generate Final Results
 Select A.ID
       ,A.Measure
       ,MinVal  = min(Measure2)
       ,MaxVal  = max(Measure2)
       ,Mean    = max(B.Mean)
       ,Median  = isnull(Avg(IIF(ExtRowNr between MednRow1 and MednRow2,Measure2,null)),A.Measure)
       ,ModeR1  = isnull(max(IIf(ModeHits>1,D.Mode,null)),min(Measure2))
       ,ModeR2  = isnull(max(IIf(ModeHits>1,D.Mode,null)),max(Measure2))
  From  #Expd A
  Join  #Mean B on (A.ID=B.ID)
  Join  #Medn C on (A.ID=C.ID)
  Join  #Mode D on (A.ID=D.ID and ModeRowNr=1)
  Group By A.ID
          ,A.Measure
  Order By A.ID

Returns

ID          Measure MinVal  MaxVal  Mean    Median  ModeR1  ModeR2
2013-01-02  1.86    1.86    1.86    1.86    1.86    1.86    1.86
2013-01-03  1.92    1.86    1.92    1.89    1.89    1.86    1.92
2013-01-04  1.93    1.86    1.93    1.9033  1.92    1.86    1.93
2013-01-07  1.92    1.86    1.93    1.9075  1.92    1.92    1.92
2013-01-08  1.89    1.86    1.93    1.904   1.92    1.92    1.92
...
2016-07-20  1.59    1.37    3.04    2.2578  2.24    2.20    2.20
2016-07-21  1.57    1.37    3.04    2.257   2.235   2.61    2.61
2016-07-22  1.57    1.37    3.04    2.2562  2.23    2.20    2.20

两种方法均在 Excel 中得到验证

我应该补充一点,在最终查询中,您当然可以添加/删除诸如 STD、Total 之类的项目

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算中位数移动平均单位成本时使用 Over(Partition By) 的相关文章

  • 数据库索引:是好事、坏事还是浪费时间?

    这里通常建议添加索引作为性能问题的补救措施 我只讨论读取和查询 我们都知道索引会使写入速度变慢 多年来 我在 DB2 和 MSSQL 上多次尝试过这种补救措施 但结果总是令人失望 我的发现是 无论索引会让事情变得更好是多么 明显 事实证明查
  • 通过 SqlConnection/SqlCeConnection 连接到 .sdf 数据库时出现问题

    我在连接到 sdf sql 紧凑版 数据库时遇到了巨大的麻烦 我可以最初连接以提取行以验证用户名 密码 但是当我尝试通过 SqlCeConnection SqlCeCommand 命令或尝试添加项目 SqlClient SqlCommand
  • SQL SELECT 在父亲 ID 组织树中查找循环引用?

    带有循环引用的 乐趣 假设我有一个表 ELEMENTS 其中包含元素的层次结构 由父 ID 建模 对于根来说 父亲 ID 字段为空 所有其他记录都有一个非空父 id 和 自动排序的 主键 ID 的父元素 例如 使用 SELECT FROM
  • 如何使用 Linq to SQL 从存储过程中检索多行?

    我最近开始使用 Linq to SQL 想知道如何通过执行存储过程来获取多行 这是我想要使用的一个简单的 sp CREATE PROCEDURE gsp ftsmultiple SearchKey varchar 100 AS BEGIN
  • SQL 按行计数模进行分组

    我有以下示例数据 Id Name Quantity 1 Red 1 2 Red 3 3 Blue 1 4 Red 1 5 Yellow 3 因此 对于此示例 总共有 5 个红色 1 个蓝色和 3 个黄色 我正在寻找一种按颜色对它们进行分组的
  • Java - oracle.jdbc.dcn.DatabaseChangeEvent - 获取更改的行

    我正在使用 oracle jdbc dcn DatabaseChangeEvent 来从 Oracle DB 获取事件通知 public class TListener implements DatabaseChangeListener p
  • 按 IN 值列表排序

    我在 PostgreSQL 8 3 中有一个简单的 SQL 查询 它捕获了一堆评论 我提供一个sorted的值列表IN构造在WHERE clause SELECT FROM comments WHERE comments id IN 1 3
  • 如何从函数依赖中获取最小密钥?

    我需要一些帮助和指导 我有以下关系 R A B C D E F 以及函数依赖集 F AB gt C A gt D D gt AE E gt F R 的主键是什么 如果我应用推理规则 我会得到这些额外的函数依赖项 D gt A D gt E
  • SQL CLR 内的 WCF 客户端

    我知道它不受支持 而且我知道这甚至不是一个好主意 但是 我希望在 SQL 表值函数中拥有一个 WCF 客户端 我 看似 注册了正确的程序集 但在运行我的客户端时 我收到 WCF 错误 Msg 6522 Level 16 State 1 Li
  • 在 SQL Server 中增加一个整数

    菜鸟问题在这里 每次我更改 SQL Server 2008 R2 表中的某个记录时 我都想增加一条 RevisionId 记录 为此 我使用以下语法 UPDATE TheTable SET RevisionId SELECT Revisio
  • Oracle 求两个时间戳的平均值

    我不明白这有多难 但我似乎无法在任何地方找到解决方案 它是针对日期完成的 但我看不到让它适用于时间戳 我正在尝试做 select avg last timestmp ref timestmp as average from param 它一
  • 如何在 postgresql 的“tablefunc”查询中包含空值?

    我正在尝试使用crosstab http www postgresql org docs 9 1 static tablefunc html函数于postgresql创建一个pivot table 但是 我很难理解如何在查询中构建 SQL
  • MySQL Select 查询 - 仅获取值的前 10 个字符

    好的 这就是问题所在 我有一个包含一些列的表 主题 是其中一列 无论 主题 字段包含一个包含 100 个字母的字符串 我都需要从 主题 字段获取前 10 个字母 例如 Table tbl 列 id subject value SQL查询 S
  • 将一个巨大的字符串参数传递给存储过程

    我有一个存储过程 它有两个参数 ID 和日期 当我将大文本传递给 ID 参数时 仅考虑部分文本 就好像文本在某个地方被剪切一样 我想这是因为当我执行存储过程时如下 exec proc 1 2 3 4 20100101 一切正常 但是当我使用
  • 如何选择非“唯一”行

    我有下表 我必须从中获取非唯一行 id idA infos 0 201 1899 1 205 1955 2 207 1955 3 201 1959 我想获取该列的所有行infos 具有相同的idA至少有两行的值 上表的查询输出必须是 inf
  • 何时在 SQL 语句中使用单引号?

    我知道当我处理 TEXT 类型的数据时应该使用它 我猜是那些回退到 TEXT 的数据 但这是唯一的情况吗 Example UPDATE names SET name Mike WHERE id 3 我正在用 C 编写 SQL 查询自动生成
  • 使用一条语句在 MySQL 中添加多列

    我试图将多个列添加到 phpMyAdmin 中的现有表中 但我不断收到相同的错误 1064 你的 SQL 语法有错误 检查与您的 MySQL 服务器版本相对应的手册以获取正确的语法 我在写信 ALTER TABLE WeatherCente
  • 如何通过csv文件仅更新sql表的一列

    我有一个 csv 文件包含一些数据 在我的 Sql 数据库中 我有一个具有多个列名的表 现在我只想通过 csv 文件更新一列 谢谢 你可以这样尝试 Import the csv file to a temp table Update you
  • SQLPLUS 保存到文件

    我必须为我的数据库类使用 SQLPLUS 我们的第一个作业是简单的保存 我按照说明进行操作 我正在使用 PuTTY 访问 sqlplus 在本练习中使用以下 SQL 命令 并尝试使用 SAVE 和 SPOOL 命令将 SQL 命令和输出保存
  • 如何根据某些条件跳过 MSSQL 游标中的一行(迭代)?

    如何根据某些条件在 MSSQL 游标中跳过一行 迭代 我有一个可迁移数千条记录的 DTS 并且根据某些条件 某些记录不需要迁移 因为它们是重复的并且想要跳过这些记录 知道如何在 MSSQL Cursor 中完成此操作吗 我想最简单的方法是在

随机推荐

  • Chrome 中的全圆 SVG 圆圈?错误解决方法

    目前 Chrome 中存在一个错误 它会赋予 SVG 圆圈边缘 使它们看起来像停车标志 https www google se search q stop 20sign https code google com p chromium is
  • Flutter C++ 与 dart::ffi 的绑定

    我正在尝试为 C 代码编写一个包装器包 在我们的应用程序中进行一些数据分析 我找到了这个很棒的帖子 https stackoverflow com a 61597535 17552354这显示了做到这一点所需的主要步骤 我更像是一个 C C
  • 如何向 JSF 输入组件添加占位符属性?

    使用 html5 时 这行代码不应该渲染一个带有占位符文本 fill me 的输入文本字段吗
  • Kafka JDBC 连接器中的自定义分区分配

    我有一个用例 我需要编写自定义逻辑来根据消息中的某些关键参数分配分区 我对此做了一些研究 发现卡夫卡转换支持覆盖转换接口中的某些方法 但我无法在 git hub 或其他地方执行一些示例代码 有人可以分享示例代码或 git hub 链接来在
  • Android 工具栏溢出菜单更改文本颜色并将菜单填充到屏幕

    there 我面临更改工具栏 操作栏溢出菜单项的文本颜色的问题 我做了太多谷歌搜索和阅读 Stackoverflow 答案 但它无法解决我的问题 目前我正在将黑色添加到溢出菜单项中 我想要的是 1 我想将菜单项的颜色从黑色更改为白色 2 我
  • 黑莓 - 等待屏幕[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我正在黑莓java开发中开发一个应用
  • 从 python 脚本中使用游标输出参数调用 oracle 存储过程

    我正在尝试从 python 脚本调用带有 2 个输入和 1 个输出参数的 Oracle 存储过程 我遇到的问题是传递游标输出参数 Oracle 存储过程本质上是 PROCEDURE ci lac state LAC ID IN IN VAR
  • 使用 JavaScript 通过“阅读更多”和“阅读更少”截断文本

    如果我错误地提出了这个问题 或者如果之前有人问过并回答过这个问题 我很抱歉 我的搜索发现了类似的基于 JQuery 的问答 我正在寻找一个纯 JavaScript 解决方案 var len 100 var p document getEle
  • 使用 Fortuna PRNG 在计数器模式下使用 AES 进行随机访问加密:

    我正在构建基于 AES 的文件加密 该加密必须能够在随机访问模式下工作 访问文件的任何部分 例如 可以在 Counter 中使用 AES 但众所周知 我们需要一个不会使用两次的唯一序列 在这种情况下 可以使用简化的 Fortuna PRNG
  • 如何在 Angular 7 的表格上使用 Ngx-pagination

    嗨 我有一个清单 例如 0 姓名 Manu 年龄 21 爱好 Array 4 1 姓名 Anu 年龄 20 爱好 Array 3 2 姓名 nandu 年龄 22 爱好 Array 5 我需要在表格上显示这一点 所以我正在执行下面的代码 t
  • igraph - 邻居作为子图 - make_ego_graph() 作为单个图

    我想构造一个有向网络图的子图 其中所有顶点共享某个顶点属性 例如 V Grph year 1952 及其一阶 直接 邻居 基于仅在出度上 我试过了ego make ego graph neighbors and adjacent verti
  • 如何静默 cvxopt 求解器 [Python]?

    每当我在终端中运行 Python cvsopt 求解器时 它都会打印 pcost dcost gap pres dres 0 8 0742e 00 7 3715e 00 3e 03 5e 01 4e 15 1 6 6241e 01 7 28
  • 如何使用 dplyr 将函数应用于所有非 group_by 列?

    我正在尝试使用 dplyr 包将函数应用于 data frame 中未分组的所有列 我将使用aggregate aggregate Species data iris mean where mean应用于所有未用于分组的列 是的 我知道我可
  • 在 C# 中实现进度条的正确方法

    我正在学习 winforms 我给自己设定了一个简单的目标 即制作一个从空到满的进度条 这是我的畸形尝试 public partial class Form1 Form static BackgroundWorker bw new Back
  • Rails,使用控制器中文件的内容

    我有一个文件在config目录 比方说 my policy txt 我想在控制器中使用该文件的内容 就像使用简单的字符串一样 policy content of config my policy txt 如何实现这个目标 Rails是否提供
  • C 中函数指针语法的用途是什么?

    编辑 有人指出这个问题有点令人困惑 简短的版本是 为什么有一个单独的指针变量 例如 fnPtr 它指向一个函数 例如 fn 当函数名fn本身 没有参数 已经是一个指针 编辑 我正在尝试了解一些内容 并且可以使用社区有关函数指针的反馈 虽然这
  • iText 表格行距从右到左方向(阿拉伯语)

    我的应用程序是用英语和阿拉伯语两个不同版本开发的 我在 iText 中使用 rowspan 和 colspan 创建了 pdf 表 该表在英语版本中完美运行 但在阿拉伯语版本中 rowspan 不起作用 当我使用 setRunDirecti
  • 花式盒子 - 如何从单个缩略图显示幻灯片

    我的缩略图是分页的 因此任何一页上只有 6 个缩略图 大约 4 页 一个类别中总共 24 张图像 如果我将其设置在其中一个页面上 它只会显示该页面上的 6 个相关图像 如何使用 Fancybox 显示所有 24 张图像的幻灯片 提前谢谢了
  • 使用 moment.js 检查日期格式

    我正在从屏幕上的日历中获取这种类型的输入 DD MMM YYYY HH mm a 但用户可以从键盘提供日期 现在我必须检查用户是否以正确的格式提供了日期 我在我的应用程序中大量使用 moment js 并像这样验证它 if angular
  • 计算中位数移动平均单位成本时使用 Over(Partition By)

    早上好 我正在尝试计算特定仓库中每件商品的 12 个月移动平均成本 MAUC 我正在使用 2012 B 分页技巧来计算中位价格 http sqlperformance com 2012 08 t sql queries median htt