【问题标题】:In Rails- how do you get the distinct rows from X column and from that sum Y column在 Rails 中-如何从 X 列和总和 Y 列中获取不同的行
【发布时间】:2021-08-26 16:47:54
【问题描述】:

我的 rails 应用程序中有一个模型视图控制器,它从视图中提取用户输入的数据并将其放入数据库中的表中。名为“table”的表如下所示:

__X__|__Y__|__Created_At__
  A  |  1  |  2021-01-02
  B  |  5  |  2021-01-02
  C  |  3  |  2021-01-02
  A  |  4  |  2021-01-01

我需要的是一个函数来查找表 X 列中的唯一值(即按最近输入值的顺序排列的奇异 A、B、C ......所以在这种情况下,值我希望为 A 拉取自最近创建以来的第一个),然后它需要获取那些唯一值的行并拉取 Y 值并将它们加在一起。

这是我尝试过的,但没有成功:

Table.distinct(:x).sum(:y)

问题在于这似乎只是将 Y 中的所有值相加,而不是忽略底部重复的 A。

如果有什么不同,我使用的是 Rails 6.0.0

【问题讨论】:

    标签: ruby-on-rails sum distinct


    【解决方案1】:

    我不确定我是否完全理解这一点:您有一个带有 X:string 列的 Table 模型。您想获取 Table 的所有实例 Table.all 并返回它们的数组 Table.all.collect {|x| x } 然后你想按 created_at 对它们进行排序 Table.all.collect {|x| x }.sort_by{|x| x.created_at} 并保留最新的。到目前为止,这应该可以做所有事情:

    Table.all.collect {|x| x }.sort_by{|x| x.created_at}.uniq
    

    您所说的“获取这些唯一值的行并提取 Y 值并将它们相加”是什么意思?对所有 Y 值求和?还是将 Xs 和 Ys 相加? X个整数要相加吗?

    【讨论】:

    • 您好 Grimhamr,感谢您的回复!我的意思是,在删除所有在 X 列中具有重复值的行之后,我需要它对 Y 列求和(因此它会删除所有较旧的重复行,只保留最新的)。因此,例如在上表中,我需要它从等式中删除第二个 A 行。所以总和只包括 1、5 和 3。所以结果是 9。
    • @jdk 好的,在这种情况下,Table.all.collect {|x| x }.sort_by{|x| x.created_at}.uniq 行应该为您提供 Table 的所有 X 唯一实例。然后你应该能够做到:Table.all.collect {|x| x }.sort_by{|x| x.created_at}.uniq.collect {|x| x.y}.sum 如果我理解这一点,将它们加在一起
    • 谢谢!该计算仍然给出与我尝试过的相同的数字(即 1+5+3+4 = 13)。我不确定为什么它不会删除最后一个值。有什么可能导致这种情况吗?
    • 这应该会给出所有唯一的、最新的 X:unique_x = Table.all.collect {|x| x }.sort_by{|x| x.created_at}.uniq 您应该能够使用 Table.where(X: unique_x}) 获得唯一的最新行。那样有用吗?很抱歉造成混乱,但表名和列名让我头疼
    • 你能更新你的问题来解释你想要什么(例如“所以例如在上表中,我需要它从等式中删除第二个 A 行。所以总和只包括 1、5 , 和 3. 所以结果是 9.") ?正如所写的那样,它非常令人困惑。
    【解决方案2】:

    如果您使用的是 postgres,它支持“distinct on”,这使得直接在数据库中执行此操作相对容易。看起来像:

    SELECT SUM(distinct_on_x.Y) 
    FROM (
      SELECT distinct ON (X) Y 
      FROM table 
      ORDER BY created_at DESC
    ) AS distinct_on_x
    

    您可以直接使用select_values 执行此操作,例如:

    select_distinct_count_sql = <<-SQL
    SELECT SUM(distinct_on_x.Y) 
    FROM (
      SELECT distinct ON (X) Y 
      FROM table 
      ORDER BY created_at DESC
    ) AS distinct_on_x
    SQL
    Table.connection.select_values(select_distinct_count_sql)
    

    如果您只想要不同的行,以便将它们汇总到内存中,您可以这样做:

    Table.select("DISTINCT ON (X) *").order("X, created_at")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-13
      • 1970-01-01
      • 1970-01-01
      • 2018-02-13
      • 2019-08-17
      • 2017-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多