【问题标题】:Give a non-constant value to interval expression给区间表达式一个非常量值
【发布时间】:2020-11-14 18:07:11
【问题描述】:

对于下面的sql表达式:

some_timstamp_field RANGE BETWEEN INTERVAL '5' second PRECEDING AND CURRENT ROW

我想将常量值'5' 更改为我表中某个字段的值(因此该值不会是常量)。

有可能吗?

【问题讨论】:

  • 我认为这在 Vertica 的窗框规格中是不可能的。您可能会用样本数据和所需结果提出另一个问题,看看是否有其他方法可以解决您想要做的事情。
  • 尝试动态 SQL,即通过 shell 或 Python 脚本编写 SQL。你从那里管理你的区间变量。
  • 在几乎所有 DBMS 中至少大致遵守 OLAP 函数中的 ANSI 标准,RANGE BETWEEN PRECEDING ... AND FOLLOWING ... 间隔表达式必须是常量文字。正如@minatverma 指出的那样,生成 SQL 的 SQL 可以成为您的朋友。但是,例如,尝试将两组不同的标识符放在您要粘贴到问题中的时间序列数据样本中,每个标识符在RANGE 中需要不同的间隔,以及您需要实现的目标。 Vertica 具有时间序列功能,可以帮助您以不同方式解决业务问题

标签: sql vertica


【解决方案1】:

对于窗框外的动态间隔表达式,您可以使用 CAST(val AS INTERVAL interval_name):

SELECT NOW(), NOW() - CAST(interval_col AS INTERVAL SECOND)
FROM
(
        SELECT 5 AS interval_col UNION ALL
        SELECT 10
)t

但是对于窗口框架是不允许的,你会得到错误:

ERROR: Window frame logical or physical offset must be a constant

更新: 假设您想根据当前记录时间戳计算动态时间范围内的记录数,解决方案可能如下:

WITH intervals AS
(
        SELECT '1 seconds' AS interval_name, CAST(1 AS INTERVAL SECOND) AS interval_value UNION ALL
        SELECT '5 seconds', CAST(5 AS INTERVAL SECOND) UNION ALL
        SELECT '10 seconds', CAST(10 AS INTERVAL SECOND)
), tnow AS
(
        SELECT NOW() AS ts
), tsdata AS(
        SELECT 4 as id, ts FROM tnow UNION ALL
        SELECT 3, ts - INTERVAL '3 second' FROM tnow UNION ALL
        SELECT 2, ts - INTERVAL '6 second' FROM tnow UNION ALL
        SELECT 1, ts - INTERVAL '20 second' FROM tnow
)
SELECT i.interval_name, t1.Id, t1.ts, COUNT(t2.id)
FROM tsdata t1
CROSS JOIN intervals i 
LEFT JOIN tsdata t2 ON t2.ts BETWEEN t1.ts - i.interval_value AND t1.ts
GROUP BY 1,2,3
ORDER BY 1,2,3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多