每个集群的平均价格

Posted

技术标签:

【中文标题】每个集群的平均价格【英文标题】:Average price per Cluster 【发布时间】:2020-01-14 23:04:46 【问题描述】:

我正在测试这段代码。

SELECT ID, Cluster, Date, Price,
    AVG(Price) OVER (PARTITION BY Cluster ORDER BY Date ROWS BETWEEN 171 PRECEDING AND CURRENT ROW) As ClusterAverage
FROM tblCluster
WHERE LEN(ID) = 9 AND IDNOT LIKE '%[^a-Z0-9]%'
   AND Cluster in ('430.00')

我想我会得到一个 ClusterAverage 的平均价格。我认为这就是'PARTITION BY Cluster' 所做的。相反,我明白了。

ID          Cluster Date        Price       ClusterAverage
50064FAL8   430     6/14/2019   115.5827    115.5827
50064FAL8   430     6/17/2019   115.694     115.63835
50064FAL8   430     6/19/2019   116.5761    115.9509333
50064FAL8   430     6/21/2019   116.1692    116.0055
50064FAL8   430     6/25/2019   117.2248    116.24936
50064FAL8   430     6/27/2019   117.0839    116.38845
50064FAL8   430     6/28/2019   117.0156    116.4780429
50064FAL8   430     6/30/2019   118.2286    116.6968625

在这种情况下,我只有一个 ID 和一个集群,但在大多数情况下,我会在一个集群中拥有多个 ID 号。最后,我要返回 171 天,因为每个 ID 最多可以有 171 天的数据,但它可以少得多,比如每个 ID 不到 10 天的数据。我想知道是否将其编码为 171 是这样做的方法,还是每个 ID 的某种 count-max-days。

【问题讨论】:

你想要的实际结果集是什么?听起来您几乎只需要一个简单的非窗口 AVG() 聚合。 【参考方案1】:

实际上,您的平均值是在滚动的最后 171 行中计算得出的,因此它会随每一行而变化。

我认为您希望在 WHERE 子句中的日期上使用 过滤器,而在没有 ORDER BY 的情况下使用 OVER()

SELECT 
    ID, 
    Cluster, 
    Date, 
    Price,
    AVG(Price) OVER (PARTITION BY Cluster) As ClusterAverage
FROM tblCluster
WHERE 
    LEN(ID) = 9 
    AND ID NOT LIKE '%[^a-Z0-9]%'
    AND Cluster in ('430.00')
    AND Date > DATEADD(day, 171, getdate())

如果您需要对计算平均值的日期范围进行更细粒度的控制,您还可以使用条件聚合:

SELECT 
    ID, 
    Cluster, 
    Date, 
    Price,
    AVG(CASE WHEN Date > DATEADD(day, 10, getdate()) THEN Price END) 
        OVER (PARTITION BY Cluster) As ClusterAverageLast10Days,
    AVG(CASE WHEN Date > DATEADD(day, 20, getdate()) THEN Price END) 
        OVER (PARTITION BY Cluster) As ClusterAverageLast20Days,
    AVG(Price) OVER (PARTITION BY Cluster) As ClusterAverageOverall
FROM tblCluster
WHERE 
    LEN(ID) = 9 
    AND ID NOT LIKE '%[^a-Z0-9]%'
    AND Cluster in ('430.00')
    AND Date > DATEADD(day, 171, getdate())

【讨论】:

也许我没有像我应该的那样描述这个问题,但我认为你把它钉在了 GMB 上!现在对我来说已经晚了。我明天要仔细看看。谢谢。【参考方案2】:

您看到的是价格的滚动平均值。

窗口函数正在查看当前行“之前”的所有行。因此输出中的第一行与价格相同,第二行是前 2 行的平均值,以此类推。

我认为您需要创建一个 CTE,对每个集群的价格(如果需要,还包括 ID)进行平均,然后将 JOIN 返回到 ID 和集群上

【讨论】:

【参考方案3】:

按 ID 将分区添加到现有的分区集群为

Partition by ID, CLUSTER..

正如您所说,数据也具有 id 明智的聚类,您可以像上面一样添加此 id 以产生相同的结果。现在返回的平均值将是 idwise 聚类行平均值

【讨论】:

【参考方案4】:

看起来您正在寻找的是在 ID 和集群级别分组的简单平均值。如果是这样:

SELECT ID, Cluster,
    AVG(Price) as ClusterAverage
FROM tblCluster
WHERE LEN(ID) = 9 AND IDNOT LIKE '%[^a-Z0-9]%' AND Date>DATEADD(day,-171,GETDATE())
GROUP BY ID, Cluster

【讨论】:

以上是关于每个集群的平均价格的主要内容,如果未能解决你的问题,请参考以下文章

计算2支股票的M天运动平均价格

计算没有辅助列/表的平均投资价格

使用子查询将价格列与类别的平均价格进行比较

python 计算时间加权平均价格:权衡近期价格

尝试设置子查询以将平均价格与给定类别的所有价格进行比较

SAP材料采购中 移动平均价/标准价 和业务里的 计划价格和实际价格 的关系