我一直在网上搜索,我没有任何线索。
基本上,有两种选择:
1) 使用 Subscriber.all 从数据库中检索所有行 并使用 Enumerable.group_by 在 Rails 应用程序中按天聚合:
@subscribers = Subscriber.all
@subscriptions_per_day = @subscribers.group_by { |s| s.created_at.beginning_of_day }
我认为这是一个非常糟糕的主意。从数据库中检索所有行对于小型应用程序来说是可以接受的,但它根本无法扩展。数据库聚合和日期函数来拯救!
2) 使用聚合和日期函数在数据库中运行 SQL 查询:
Subscriber.select('STRFTIME("%Y-%m-%d", created_at) AS day, COUNT(*) AS subscriptions').group('day')
将在此 SQL 查询中运行:
SELECT STRFTIME("%Y-%m-%d", created_at) AS day, COUNT(*) AS subscriptions
FROM subscribers
GROUP BY day
好多了。现在,聚合是在针对此类任务优化的数据库中完成的,并且每天只有一行从数据库返回到 Rails 应用程序。
...但是等等...现在该应用程序必须在我使用 MySQL 的生产环境中上线!
将 STRFTIME() 替换为 DATE_FORMAT()。
如果明天我切换到 PostgreSQL 怎么办?
将 DATE_FORMAT() 替换为 DATE_TRUNC()。
我喜欢使用 SQLite 进行开发。简单易行。 我也喜欢 Rails 与数据库无关的想法。 但是为什么 Rails 不提供一种方法来翻译执行完全相同的事情但在每个 RDBMS 中具有不同语法的 SQL 函数(这种差异真的很愚蠢,但是嘿,提示已经太晚了它)?
对于 Rails 应用程序的基本功能:计算每天、每月或每年的订阅量,我无法相信我在 Web 上找到的答案如此之少。
告诉我我遗漏了什么:)
我发布这个问题已经有几年了。 经验表明我应该为开发和生产使用相同的数据库。所以我现在认为与数据库无关的要求无关紧要。
最佳答案
我最终编写了自己的 gem。检查一下并随时贡献: https://github.com/lakim/sql_funk
它允许您调用电话:
Subscriber.count_by("created_at", :group_by => "day")
关于sql - rails : How to build statistics per day/month/year or How database agnostic SQL functions are missing (ex. : STRFTIME, DATE_FORMAT,DATE_TRUNC),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4028878/