【问题标题】:How to get the latest 2 rows ( PostgreSQL )如何获取最新的 2 行(PostgreSQL)
【发布时间】:2016-04-07 03:04:50
【问题描述】:

我需要您的帮助来修改查询以完成要求。

根据 GATHER_TIME,我想显示 NAME 的值。 查询每 1 分钟运行一次,它应该一直得到 2 行。 如果当时没有数据,它应该获取过去(1 分钟前)的 Name 数据。

这里,具体要求是我不应该考虑时间戳值(GATHER_TIME)中的秒值。

我尝试进行如下查询。 它只获取最新数据。

你能帮帮我吗?

查询

select NAME,sum(VALUE)
FROM TestTable
WHERE substring(to_char(gather_time,'YYYY-MM-DD HH24:MI:SS'),1,16) IN ( SELECT MAX(substring(to_char(gather_time,'YYYY-MM-DD HH24:MI:SS'),1,16)) FROM TestTable )
GROUP BY NAME

表格数据

NAME    COL1   COL2    GATHER_TIME         VALUE
------------------------------------------------
first   prince PQ1     2015-12-29 13:10:33 11
first   prince PQ2     2015-12-29 13:10:33 14
first   prince PQ3     2015-12-29 13:10:33 18
first   prince PQ4     2015-12-29 13:10:33 19
second  prince TT1     2015-12-29 13:10:59 20
second  prince TT2     2015-12-29 13:10:59 29
second  prince TT3     2015-12-29 13:10:59 43
first   prince PQ1     2015-12-29 13:11:37 71
first   prince PQ2     2015-12-29 13:11:37 74
first   prince PQ3     2015-12-29 13:11:37 78
first   prince PQ4     2015-12-29 13:11:37 79

要求的结果

@ Query time: 2015-12-29 13:10:59
first       62
second      92

@ Query time: 2015-12-29 13:11:59
first       302
second      92

补充:

对不起。我应该放更详细的测试数据。更新了。

如果在 GROUP BY:: 中使用了两列(需要验证)

SELECT DISTINCT ON (name,col1,gather_time) name,col1,SUM(value) 
FROM test_table
GROUP BY name,col1,gather_time
ORDER BY gather_time DESC
LIMIT 2;

【问题讨论】:

  • 使用 order by gather_timelimit 2 ,我认为这会给你想要的结果
  • 问题描述不正确; 2 示例语句应具有一致的ORDER;对于2015-12-29 13:10:59 查询时间,您有ASC 订单,但对于查询时间2015-12-29 13:11:59,您有DESC

标签: sql postgresql greatest-n-per-group


【解决方案1】:
-- DDL
CREATE TABLE test_table(
  name TEXT,
  col2 TEXT,
  gather_time TIMESTAMP,
  value INTEGER
);

--sample data
INSERT INTO test_table  VALUES
  ('first','PQ1','2015-12-29 13:10:33'::TIMESTAMP, 11),
  ('first','PQ2','2015-12-29 13:10:33'::TIMESTAMP, 14),
  ('first','PQ3','2015-12-29 13:10:33'::TIMESTAMP, 18),
  ('first','PQ4','2015-12-29 13:10:33'::TIMESTAMP, 19),
  ('second','TT1','2015-12-29 13:10:59'::TIMESTAMP, 20),
  ('second','TT2','2015-12-29 13:10:59'::TIMESTAMP, 29),
  ('second','TT3','2015-12-29 13:10:59'::TIMESTAMP, 43),
  ('first','PQ1','2015-12-29 13:11:37'::TIMESTAMP, 71),
  ('first','PQ2','2015-12-29 13:11:37'::TIMESTAMP, 74),
  ('first','PQ3','2015-12-29 13:11:37'::TIMESTAMP, 78),
  ('first','PQ4','2015-12-29 13:11:37'::TIMESTAMP, 79);

--query to run every minute
SELECT name,SUM(value) FROM test_table
  WHERE gather_time <= now()
  GROUP BY name,gather_time
  ORDER BY gather_time DESC
  LIMIT 2;

OR 使用函数:

CREATE OR REPLACE FUNCTION get_2latest_agg_rows(qtime timestamp) 
  RETURNS TABLE (
    order_name TEXT,
    sum_value BIGINT
 ) AS $$
BEGIN
  RETURN QUERY
  SELECT name as order_name,SUM(value) as agg_result FROM test_table
  WHERE gather_time <= qtime::TIMESTAMP
  GROUP BY name,gather_time
  ORDER BY gather_time DESC
  LIMIT 2;
END;
$$ LANGUAGE plpgsql;

--sample run
SELECT * FROM get_2latest_agg_rows('2015-12-29 13:11:59'::TIMESTAMP);

【讨论】:

  • 谢谢。我更新了测试数据。你能再给我建议吗?
  • 哦。精彩的!。我将介绍 DISTINCT ON 关键字。再次感谢您。
  • 如果应该在 GROUP BY 中使用两列,我提出的查询是否有意义?
  • 如果NAME列中有另一个值,例如'第三','第四'?我们必须增加 LIMIT 值吗? LIMIT 关键字在此查询中是必需的吗?
  • DISTINCT 是不必要的,因为你有 GROUP BY
【解决方案2】:

如果您将按gather_time 排序并使用limit 2 来获取最新的2 行会怎样? 这符合要求吗?

select NAME,sum(VALUE) FROM TestTable ORDER BY gather_time DESC LIMIT 2;

【讨论】:

  • 您不能使用聚合函数 (SUM),除非它是唯一返回的列,或者您包含 GROUP BY
猜你喜欢
  • 1970-01-01
  • 2016-09-01
  • 2015-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
相关资源
最近更新 更多