栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Rails通过:created_at对表进行分组,返回:status列的计数,然后对:status列进行子分组,并包含每个唯一值的计数

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Rails通过:created_at对表进行分组,返回:status列的计数,然后对:status列进行子分组,并包含每个唯一值的计数

我用另一种方法添加了第二个答案,我相信它会更好,因为它高效并且可以转换为数据库视图。

每当我遇到很多对数据库的重复点击或无法很好地翻译的大型,复杂查询时,我都希望使用纯SQL,因为这样可以将其用作DB中的视图。我问这个问题是因为我的SQL很差。我认为这可以适应您的需求,尤其是在“状态”字段是一组已知的可能值的情况下。这是我最初尝试的方式:

构造一个有效的SQL查询。 您可以在psql中对此进行测试。

SELECt created_at, count(status) AS total,sum(case when status = 'error' then 1 end) AS errors,sum(case when status = 'pending' then 1 end) AS pending,sum(case when status = 'sent' then 1 end) AS sentFROM notificationsGROUP BY created_at;

这应该返回一个数据透视表,如下所示:

| created_at       |total|errors|pending|sent|----------------------------------------------| Mon, 05 Oct 2015 |2572 |500   |12     |null|| Tue, 06 Oct 2015 |555  |null  |12     |50  |

太好了,任何一张表在Rails中都是一个简单的查询,它将以对象数组的形式加载它。这些对象中的每一个将具有与每一列相对应的方法。如果该行的

nil
列为null,则Rails将作为该值传递。

在Rails中测试

@stats = Notification.where(user: users).find_by_sql("SELECt created_at, count(status)   AS total,  sum(case when status = 'error' then 1 end) AS errors,  sum(case when status = 'pending' then 1 end) AS pending,  sum(case when status = 'sent' then 1 end) AS sent  FROM notifications  GROUP BY created_at;")

这将返回一个

Notification
对象数组…

=> [#< Notification id: nil, created_at: "2014-02-07 22:36:30">#< Notification id: nil, created_at: "2014-06-26 02:07:51">,#< Notification id: nil, created_at: "2015-04-26 21:37:09">,#< Notification id: nil, created_at: "2014-02-07 22:48:29">,#< Notification id: nil, created_at: "2014-11-04 23:39:07">,#< Notification id: nil, created_at: "2015-01-27 17:46:50">,...]

请注意,该

Notificationid:
值为nil。这是因为这些对象并不代表数据库中的实际对象,而是代表查询所产生的表中的一行。但是现在您可以执行以下操作:

@stats.each do |daily_stats|  puts daily_stats.attributesend#{"created_at" => "Mon, 05 Oct 2015", "total" = 2572, "errors" => 500, "pending" => 12, "sent" => nil}#{"created_at" => "Tue, 06 Oct 2015", "total" = 555, "errors" => nil, "pending" => 12, "sent" => 50}

等等。您的

@stats
变量很容易传递到视图,在该视图中可以轻松地将其打印为
.html.erb
文件中的表格。您可以访问数组中任何Notification对象的属性,如下所示:

@stats[0].created_at  #=> "Mon, 05 Oct 2015"@stats[1].pending  #=> 12

总的来说,您已经使用一个查询来获取整个数据集。

将其存储为视图 登录到数据库上的SQL控制台并执行

CREATE VIEW daily_stats ASSELECt user_id, created_at, count(status) AS total,   sum(case when status = 'error' then 1 end) AS errors,   sum(case when status = 'pending' then 1 end) AS pending,   sum(case when status = 'sent' then 1 end) AS sentFROM notificationsGROUP BY user_id, created_at;

现在您可以得到结果

Select * FROM daily_stats;

请注意,我故意不限制用户的使用,就像您在原始问题中一样,并在SELECt中添加了user_id。我们正在直接在数据库中工作,它应该可以轻松地从该视图生成带有每个日期的所有用户统计信息的表。对于您正在做的事情,这是一个非常强大的数据集。现在,您可以在Rails中设置虚拟模型,并轻松获取所有数据,而不会扭曲Rails查询。

添加一个虚拟模型 app / models / daily_stat.rb:

class DailyStat < ActiveRecord::base  belongs_to :user  #this is a model for a view in the DB called dash_views  #class name is singular and will automatically look for the table "daily_stats" which his snake_case and plural.end

将相应的关系添加到您的

User
模型:

class User < ActiveRecord::base  has_many :daily_statsend

现在,您可以按用户熟悉的方式访问统计信息。

users = [2]DailyStat.where(user: users)   => AllStat Load (2.8ms)  SELECT "all_stats".* FROM "all_stats" WHERe "all_stats"."category_id" = 2   => [ #<AllStat user_id: 2, created_at: "2014-02-14 00:30:24", total: 300, errors: 23, pending: nil, sent: 3>,        #<AllStat user_id: 2, created_at: "2014-11-29 00:18:28", total: 2454, errors: 3, pending: 45, sent: 323>,        #<AllStat user_id: 2, created_at: "2014-02-07 22:46:59", total: 589, errors: 33, pending: 240, sent: 68>...]

并在另一个方向:

user = User.firstuser.daily_stats #returns array of that users DailyStat objects.

关键是“从最低层次解决问题”。解决数据库中的数据查询问题,然后使用Rails进行操作并显示它。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/612183.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号