Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL选择时间段内的最高值_Sql_Ruby On Rails_Postgresql_Greatest N Per Group - Fatal编程技术网

PostgreSQL选择时间段内的最高值

PostgreSQL选择时间段内的最高值,sql,ruby-on-rails,postgresql,greatest-n-per-group,Sql,Ruby On Rails,Postgresql,Greatest N Per Group,使用Rails,我试图执行一个SQL命令来返回一个包含某个用户每天最高值的行数组 例如: user_id(integer) | created_at(datetime) | score(integer) -------------------+--------------------------------+--------------- 1 | "2015-07-27 21:35:24" | 100

使用Rails,我试图执行一个SQL命令来返回一个包含某个用户每天最高值的行数组

例如:

  user_id(integer) |        created_at(datetime)    | score(integer)
-------------------+--------------------------------+---------------
              1    |      "2015-07-27 21:35:24"     |         100
              1    |      "2015-07-27 21:35:24"     |         123
              2    |      "2015-07-27 21:35:24"     |         101
              2    |      "2015-07-27 21:35:24"     |         122
              3    |      "2015-07-27 21:35:24"     |         103
              3    |      "2015-07-27 21:35:24"     |         115
              1    |      "2015-07-26 21:35:24"     |         116
              1    |      "2015-07-26 21:35:24"     |         151
              2    |      "2015-07-26 21:35:24"     |         122
              2    |      "2015-07-26 21:35:24"     |         134
              3    |      "2015-07-26 21:35:24"     |         123
              3    |      "2015-07-26 21:35:24"     |         111
              1    |      "2015-07-25 21:35:24"     |         129
              1    |      "2015-07-25 21:35:24"     |         152
              2    |      "2015-07-25 21:35:24"     |         120
              2    |      "2015-07-25 21:35:24"     |         109
              3    |      "2015-07-25 21:35:24"     |         142
              3    |      "2015-07-25 21:35:24"     |         131
预期成果:

  user_id(integer) |        created_at(datetime)    | score(integer)
-------------------+--------------------------------+---------------
              1    |      "2015-07-27 21:35:24"     |         123
              2    |      "2015-07-27 21:35:24"     |         122
              3    |      "2015-07-27 21:35:24"     |         115
              1    |      "2015-07-26 21:35:24"     |         151
              2    |      "2015-07-26 21:35:24"     |         134
              3    |      "2015-07-26 21:35:24"     |         123
              1    |      "2015-07-25 21:35:24"     |         152
              2    |      "2015-07-25 21:35:24"     |         120
              3    |      "2015-07-25 21:35:24"     |         142
我一直在组合各种连接,
拥有
和其他方法,但都没有用。我无法让它过滤结果。通过
select
ing每日最大值,我取得了一些进步,但是我无法根据每个
user\u id
筛选出较低的值。我在Rails中使用了multiple
groupby
map
实现了这一点,但速度非常慢,因为它必须在整个数组中重新迭代,而且有很多记录,这可能需要一些时间

编辑:

我的解决办法如下:

    all_scores_in_time_period = UserScore
      .where("EXTRACT(MONTH FROM created_at) = ?", Date::MONTHNAMES.index(params[:month_control]))
      .where("EXTRACT(YEAR FROM created_at) = ?", params[:year_control])
      .select("DISTINCT ON(DATE(created_at), user_id) *")
      .order("DATE(created_at) desc")

这首先按月/年进行过滤,然后按每个用户每天的最高分数返回用户列表。

您可以使用
distinct on()
,这是
distinct
操作符的Postgres扩展:

select distinct on (user_id, created_at) user_id, created_at, score
from the_table
order by user_id, created_at, score desc;
如果您希望使用标准SQL解决方案,也可以使用窗口函数实现:

select user_id, created_at, score
from (
  select user_id, created_at, score, 
         row_number() over (partition by user_id, created_at order by score desc) as rn
  from the_table
) as t
order by user_id, created_at;
使用
distinct on()
的解决方案在Postgres中通常更快

通过一个窗口功能,你还可以处理关系:当一个用户在一天中多次获得相同(最高)分数时。带有
row\u number()
的解决方案将仅为每个(用户id,创建时间)返回一行。如果希望所有行具有相同(最高)分数,则需要使用
densite\u rank()

编辑

如果要忽略时间戳列的时间部分,只需将其强制转换为日期:

created_at::date

“21:35:24”对于所有阻止对解决方案进行彻底测试的日子(因为它有效地将时间戳转换为最新时间),请提供更多真实的时间戳。@Dzenly-时间不是必需的。无论如何,它都要按日期过滤,而不是按日期时间过滤。我写了《泰晤士报》,试图更明确一些,但你是对的——它确实有点混淆了要点。
distinct on
是我一直在寻找的。非常感谢。