【问题标题】:How to get the average maximum value between rows with a given step?如何获得给定步骤的行之间的平均最大值?
【发布时间】:2021-12-07 11:52:09
【问题描述】:

我需要用 n 步获取两行之间的平均最大值。如果步长为 6(n = 6),我需要找出 1 到 6(不包括)行之间的平均最大值,然后是 6 和 12(不包括)之间的平均值,以此类推。步数和行数都可以不同。

|id|eventDate |  x  | y |
-------------------------
|1 |10.10.2021| 0.33|0.4|
-------------------------
|2 |10.11.2021| 0.34|0.5|
-------------------------
|3 |10.12.2021| 0.35|0.6|
-------------------------
|4 |10.13.2021| 0.36|0.7|
-------------------------
|5 |10.14.2021| 0.37|0.8|
-------------------------

Step = 3 (n = 3) 结果应该是

|id|eventDate |        x              |          y           |
--------------------------------------------------------------
|3 |10.12.2021| avr between id 1 and 3|avr between id 1 and 3|
--------------------------------------------------------------
|5 |10.14.2021| avr between id 3 and 5|avr between id 3 and 5|
--------------------------------------------------------------

【问题讨论】:

  • 您要求的“结果”不包括平均数。不包括在内,您的意思是 n=6 平均为 2 -> 5,而不是 1 和 6?你的问题不是很清楚。
  • 如果 n = 6 将计算第 1,2,3,4,5,6 行范围内的平均值
  • 所以它们是包容性的,就像 BETWEEN 命令 stackoverflow.com/questions/749615/… "BETWEEN 运算符是包容性的。" “如果 test_expression 的值大于或等于 begin_expression 的值且小于或等于 end_expression 的值,则 BETWEEN 返回 TRUE。” "

标签: sql clickhouse


【解决方案1】:

如果您希望 SQL 尝试返回组,如果您的 DBMS 支持,您可以使用 NTILE 之类的东西。 https://docs.microsoft.com/en-us/sql/t-sql/functions/ntile-transact-sql?view=sql-server-ver15

我添加了第 6 行以使组相等。在您的问题中,您指定您希望将 1-3 和 3-5(包括)分组,这将使平均第 3 行加倍。我不确定这是否是您的意图。

这适用于 MSSQL:

CREATE TABLE #Temp(
    ID INT,
    eventDate DATE,
    x NUMERIC(3,2),
    y NUMERIC(3,2)
)

DECLARE @Step INT = 3

INSERT INTO #Temp
VALUES 
(1,'10.10.2021',0.33,0.4),
(2,'10.11.2021',0.34,0.5),
(3,'10.12.2021',0.35,0.6),
(4,'10.13.2021',0.36,0.7),
(5,'10.14.2021',0.37,0.8),
(6,'10.15.2021',0.38,0.9)

DECLARE @GroupCount INT = (SELECT COUNT(*) FROM #Temp) / @Step

SELECT MAX(ID) as ID, MAX(eventDate) as eventDate, AVG(x) as AvgX, AVG(y) as AvgY
FROM(
    SELECT *, NTILE(@GroupCount) OVER(ORDER BY ID) Grp
    FROM #Temp
) as t
GROUP BY t.Grp
DROP TABLE #Temp
ID eventDate AvgX AvgY
3 2021-10-12 0.340000 0.500000
6 2021-10-15 0.370000 0.800000

否则您可能不得不求助于 CURSOR 或 WHILE 循环。

【讨论】:

  • 如果生成的 UUID 不是 id,这会起作用吗?
  • 是的,即使使用日期也应该没问题。
  • 这种查询部分解决了问题,但保留了不必要的行 =========================== =================== SELECT eventDate, avg(x) OVER (ORDER BY eventDate ROWS BETWEEN 2 PRECEDING AND 当前 ROW) AS avrX, avg(y) OVER (ORDER BY eventDate ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS avrY FROM table ORDER BY eventDate
  • 我与 clickhouse 合作
  • 哦,那么我假设您需要使用它们可用的任何类似循环的函数。 Clickhouse 实际上不是 SQL,所以我不确定。 “ClickHouse 支持一种扩展的类 SQL 语言,包括数组和嵌套数据结构”。我已经更新了您问题的标签,希望有使用它经验的人可以提供帮助。
【解决方案2】:

尚不清楚您是否希望您的乐队在第一行/最后一行重叠。我怀疑你没有。也不清楚您所说的“平均最大值”是什么意思。

因此,如果您使用row_number() 将唯一的组号关联到每一行,我认为您将能够聚合。

with data as (
    select *,
        (row_number() over (order by eventDate) - 1)
          / groupSize /* aka n? */ as grp /* integer division */
    from tbl
)
select
    min(id) as min_id, min(eventDate) as min_eventDate,
    avg(x) as avg_x, avg(y) as avg_y
from data
group by grp;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-11
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多