在SQL中,我会使用类似这样的内容:
SELECT year(created_at)
FROM videos
GROUP BY year(created_at)
如何使用Rails运行此查询?
我已经尝试过了:
Video.all.group_by { |m| m.created_at.year }
...但是这将返回我所有按相应年份分组的记录,这并不完全不好,只是当我只需要知道年份时它返回数百条记录。
有指针吗?
如果您想知道我使用的是Rails 5.1.5和MariaDB(10.2.14-MariaDB-10.2.14 + maria〜xenial-log)。
答案 0 :(得分:3)
您可以执行以下操作来获得一系列独特的年份...
Video.pluck(:created_at).map{ |dt| dt.year }.uniq
答案 1 :(得分:1)
并非所有内容都可以在ActiveRecord讲话中表达,而不会在这里或那里失去效率。或有些事情根本无法表达。这就是为什么您可以运行任意SQL的原因:
Video.connection.execute("select year(created_at)....")
实际上已经阅读了您的SQL,您想要不同的记录年份吗?那么,也许这呢?应该更快(需要基准测试)。
SELECT DISTINCT YEAR(created_at) FROM videos
答案 2 :(得分:1)
结果是,pluck
接受表达式,不仅接受列名。因此,您可以这样做以获得最大效率(以可移植性为代价)。
Video.distinct.pluck("year(created_at)") # mysql
Video.distinct.pluck("extract(year from created_at)") # postgresql
与运行原始sql的效率相同(从我的其他答案中得出),但看起来有点ActiveRecord-y。
如果您想要一个便携式解决方案,那么我想不出比Mark's answer更好的了。
答案 3 :(得分:0)
如果您只希望从数据中提取年份,则可以这样做
videos = Video.group("created_at").select("videos.created_at")
它将仅获取created_at列
您可以通过created_at列中的年份访问
videos.first.created_at.year
答案 4 :(得分:0)
您也可以这样做:
Video.all.map {|u| u.created_at.year}
这将返回一个数组,其中包含每个Video
的创建年份。
答案 5 :(得分:0)
我正在使用
Event.group("strftime('%Y', created_at)")
例如:
Event.group("strftime('%Y', created_at)").count
具有输出:
{"2019"=>456}
您甚至可以通过以下方式对孩子的created_at
进行分组:
Application.group("strftime('%Y', events.created_at)")
在我的特殊情况下,这需要一个applications
有很多events
。