【问题标题】:Get most recent data to a periodic timestamp将最新数据获取到周期性时间戳
【发布时间】:2013-11-27 15:17:17
【问题描述】:

编辑

我意识到我的问题实际上有两个部分:

One of the answers 到第二个问题使用 Postgres 的SELECT DISTINCT ON,这意味着我根本不需要组。我已经在下面发布了我的解决方案。

我的数据通常会被查询以获取最新值。但是,如果我每分钟查询一次,我需要能够重现会收到什么结果,回到某个时间戳。

我真的不知道从哪里开始。我对 SQL 的经验很少。

CREATE TABLE history
(
  detected timestamp with time zone NOT NULL,
  stat integer NOT NULL
)

我选择喜欢:

SELECT
detected,
stat

FROM history

WHERE
detected > '2013-11-26 20:19:58+00'::timestamp

显然,这给了我自给定时间戳以来的所有结果。我希望每个stat 从现在回到时间戳最接近分钟。最接近的意思是“小于”。

抱歉,我没有尽全力接近答案。我对 SQL 太陌生了,不知道从哪里开始。

编辑

How to group time by hour or by 10 minutes 这个问题似乎很有帮助:

SELECT timeslot, MAX(detected)
FROM
(  
    SELECT to_char(detected, 'YYYY-MM-DD hh24:MI') timeslot, detected
    FROM
    (
        SELECT detected
        FROM history
        where
        detected > '2013-11-28 13:09:58+00'::timestamp
    ) as foo 
) as foo GROUP BY timeslot

这为我提供了最近的 detected 时间戳,间隔为一分钟。

如何获得stat? MAX 在按分钟分组的所有 detected 上运行,但 stat 无法访问。

第二次编辑

我有:

timeslot;max
"2013-11-28 14:04";"2013-11-28 14:04:05+00"
"2013-11-28 14:17";"2013-11-28 14:17:22+00"
"2013-11-28 14:16";"2013-11-28 14:16:40+00"
"2013-11-28 14:13";"2013-11-28 14:13:31+00"
"2013-11-28 14:10";"2013-11-28 14:10:02+00"
"2013-11-28 14:09";"2013-11-28 14:09:51+00"

我想要:

detected;stat
"2013-11-28 14:04:05+00";123
"2013-11-28 14:17:22+00";125
"2013-11-28 14:16:40+00";121
"2013-11-28 14:13:31+00";118
"2013-11-28 14:10:02+00";119
"2013-11-28 14:09:51+00";121

max 和 detected 是一样的

【问题讨论】:

  • 你试过MAX(检测到)吗?
  • @SamS 这将返回一个结果,但我需要自时间戳以来经过的分钟数的结果。
  • 我知道你需要什么。实现此目的的一种方法是将数据复制到另一个数据库并修改您的查询以提供大于第二个表上的最大时间戳的结果。我会尝试做一个 sqlfiddle
  • 您还可以将布尔列移动默认为 0,当您将其移动到第二个表时将其更改为 1
  • 我不确定是否要复制到另一个数据库。该表目前大约有 200 万行。

标签: sql postgresql datetime select


【解决方案1】:

我可以为您提供这个解决方案:

with t (tstamp, stat) as(
  values 
    (  current_timestamp,                         'stat1'), 
    (  current_timestamp - interval '50' second,  'stat2'),
    (  current_timestamp - interval '100' second, 'stat3'),
    (  current_timestamp - interval '150' second, 'stat4'),
    (  current_timestamp - interval '200' second, 'stat5'),
    (  current_timestamp - interval '250' second, 'stat6')
)
select stat, tstamp
from t
where tstamp in (
    select max(tstamp)
    from t
    group by date_trunc('minute', tstamp)
);

但它在 Oracle 中......也许它对你有帮助

【讨论】:

  • 我冒昧地将其转换为 Postgres 语法
【解决方案2】:

好的,再试一次:)

我使用 Microsoft 的 AdventureWorks DB 进行了尝试。我采用了其他一些数据类型,但它也应该适用于 datetimeoffset 或类似的日期时间。

所以我用循环尝试了它。当您的时间戳小于 NOW 时,请为我选择您的时间戳和时间戳之间的数据加上间隔大小。这样我就可以在一个时间间隔内获取数据,然后设置时间戳加上获取下一个时间间隔的时间间隔,直到今天 while 循环到达。 也许这是一种方式,如果不是为此感到抱歉:)

DECLARE @today date
DECLARE @yourTimestamp date
DECLARE @intervalVariable date

SET @intervalVariable = '2005-01-07' -- start at your timestamp
SET @today = '2010-12-31'

WHILE  @intervalVariable < @today -- your Timestamp on the left side
BEGIN

SELECT FullDateAlternateKey FROM dbo.DimDate
WHERE FullDateAlternateKey BETWEEN @intervalVariable AND DATEADD(dd,3,    @intervalVariable)

SET @intervalVariable = DATEADD(dd,3, @intervalVariable) -- the three is your intervale
print 'interval'
END
print 'Nothing or finished'

【讨论】:

  • 对不起,我没有很好地解释自己。想象一下,我错过了轮询我的数据库 5 分钟。我希望能够说“给我最后 5 分钟的 stat,就像我每隔 1 分钟轮询一次时那样”。
  • 呃,请不要在 SQL Server 上使用BETWEEN with date/time/timestamp types,尤其是。
【解决方案3】:

我的解决方案结合使用to_char 将时间戳剪裁到最接近的分钟,并选择具有不同分钟的第一行:

SELECT DISTINCT ON (timeslot)
to_char(detected, 'YYYY-MM-DD hh24:MI') timeslot,
detected,
stat

FROM history

ORDER BY timeslot DESC, detected DESC;

这是this answer to 'Select first row in each GROUP BY group?'到达的。

【讨论】:

  • 您确定吗,这样您每分钟会获得最新的条目,而不是在剪辑日期后进行排序时每分钟随机获得 1 个条目
  • @Armunin SELECT DISTINCT ON 使用ORDER BY 为每个时间段选择一行。
  • @Armunin 我也修复了语法。我在timeslot 周围缺少括号。
  • 感谢更新,我对 postgresql 不是很熟悉。很高兴您找到了解决方案。
猜你喜欢
  • 1970-01-01
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多