【问题标题】:Optimized and efficient SQL query with Rails 4 ActiveRecord on postgreSQL database?在 postgreSQL 数据库上使用 Rails 4 ActiveRecord 优化和高效的 SQL 查询?
【发布时间】:2014-08-22 00:37:11
【问题描述】:

如果不破解一些完全荒谬的东西,我不确定如何做到这一点,并且经验认为,有人可能会建议 1 或 2 行代码,这正是我想要的。 我不确定在哪里看,所以这是我的问题:

假设我想显示一个月至今每日注册的图表。所以我需要一个高效的sql语句。

我希望它返回这样的哈希:

{ "2014-08-01"=>83, "2014-08-02"=>67, "2014-08-03"=>109, ... }

然后我可以用它来生成一个邪恶的酷图表! =)

所以我不知道如何编写这个查询。有人能帮助我吗?谢谢...

这是我的“被黑”尝试:

h = User.group("created_at").count
   (0.7ms)  SELECT COUNT(*) AS count_all, created_at AS created_at FROM "users"  GROUP BY created_at
 #=> {nil=>5, 2014-07-27 17:19:41 UTC=>1, 2014-07-19 00:23:54 UTC=>1, 2014-08-21 18:02:58 UTC=>1, 2014-08-21 18:39:31 UTC=>1, 2014-08-21 17:32:48 UTC=>1, 2014-08-21 17:21:46 UTC=>1, 2014-08-21 18:36:21 UTC=>1, 2014-08-21 16:29:37 UTC=>1, 2014-08-21 18:54:34 UTC=>1, 2014-08-21 17:56:24 UTC=>1, 2014-08-21 18:33:20 UTC=>1, 2014-08-21 16:27:17 UTC=>1, 2014-08-21 19:16:11 UTC=>1, 2014-08-21 18:41:14 UTC=>1, 2014-08-21 18:14:12 UTC=>1, 2014-08-21 18:30:46 UTC=>1, 2014-08-21 18:28:04 UTC=>1} 

dates = h.keys.compact.map {|j| j.to_s.match(/\d*-\d*-\d*/)[0] }

 #=> ["2014-07-27", "2014-07-19", "2014-08-21", "2014-08-21", "2014-08-21", "2014-08-21", "2014-08-21", "2014-08-21", "2014-08-21", "2014-08-21", "2014-08-21", "2014-08-21", "2014-08-21", "2014-08-21", "2014-08-21", "2014-08-21", "2014-08-21"] 

signUpHash = Hash.new 0
 #=> {} 
dates.map do |date|
signUpHash[date] += 1
end
 #=> [1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] 
signUpHash
 #=> {"2014-07-27"=>1, "2014-07-19"=>1, "2014-08-21"=>15} 
signUpHash.sort.to_h
 #=> {"2014-07-19"=>1, "2014-07-27"=>1, "2014-08-21"=>15} 

所以虽然我的方法有效(有点因为它实际上并没有考虑到需要更多黑客攻击的月份)所以......(我知道有一个更好、更有效、更易读、更可靠、更受欢迎,推荐,理想......(你明白了)......这样做的方法。请指教。谢谢!=)

【问题讨论】:

  • 这是一个很棒的问题,因为这里学到的知识可以以许多有用的方式应用......!
  • 您似乎想要的是 Rails 代码,而不是 SQL。让它变得不那么有趣了:p
  • @Craig no no no ... 请为它增添趣味... 让它变得如此有趣,以至于我的头从我的身上旋转... 请把这些奇妙的知识倒在我身上——我不是讽刺......说真的,我想知道你在暗示什么......不要剥夺我的任何乐趣! [急切等待] =D

标签: sql ruby-on-rails postgresql activerecord ruby-on-rails-4


【解决方案1】:

如果直接编写 SQL,您将使用date_trunc

您没有显示表定义或示例数据,因此我无法真正对其进行测试或编写完整的查询,但一般原则是:

SELECT date_trunc('month', created_at), count(created_at)
FROM mytable
GROUP BY date_trunc('month', created_at)
ORDER BY 1;

生成每月第一天的结果集来计算对,然后这些对被简单地消耗并聚合到客户端中的哈希中。您可以在 SQL 查询中构建哈希,但这样做并没有任何好处。

请注意,created_at 上的索引不能用于此查询。如果您想将其限制在某些日期,请在created_at 上使用WHERE 子句,而不是使用生成的date_trunc'd 值。

如果你经常运行它并且需要它快速,并且不介意额外索引的额外写入开销,你可以在月份创建一个复合索引:

create index blahwhateverindexname on mytablename( (date_trunc('month', created_at) );

【讨论】:

  • date_trunc 我自己不会发现这个。现在要做一些阅读...使用 Rails 的“魔法”总是简单而有趣,但实际上知道原始 sql 查询,这只是引起...谢谢老兄!
  • 在如此短的文本中包含大量信息。不错的答案 +1 让它打开看看是否有其他人会超过你... =)
猜你喜欢
  • 2015-01-25
  • 2022-11-08
  • 1970-01-01
  • 2015-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多