在Rails中按月和按年分组

时间:2014-05-13 04:58:40

标签: ruby-on-rails postgresql

我对postgresql有疑问,我想在我的应用程序中使用rails实现

ActiveRecord::Base.connection.select_rows("SELECT to_char(date,'Mon') as mon, extract(year from date) as yyyy, SUM(CASE WHEN Title = 4 THEN Qty ELSE 0 END) AS sold FROM Transactions WHERE Store_id = 5 AND Product_id = 2 GROUP BY 1,2")

我在rails console上试过,结果是:

←[1m←[36m (2.0ms)←[0m  ←[1m
SELECT to_char(date,'Mon') as mon, extract(year from date) as yyyy, SUM(CASE WHEN Title = 4 THEN Qty ELSE 0 END) AS sold FROM Transactions WHERE Store_id = 5 AND Product_id = 2 GROUP BY 1,2 
←[0m=> [["Jul", "2013", "113"], ["Oct", "2013", "73"], ["Jun", "2013", "291"], ["Sep", "2013", "13"], [" Aug", "2013", "81"]]

结果不按月份排序。

我尝试添加ORDER BY 1,2但结果如下:

←[1m←[36m (10.0ms)←[0m  ←[1m
SELECT to_char(date,'Mon') as mon, extract(year from date) as yyyy, SUM(CASE WHEN Title = 4 THEN Qty ELSE 0 END) AS sold FROM Transactions WHERE Store_id = 5 AND Product_id = 2 GROUP BY 1,2 ORDER BY 1,2
←[0m=> [["Aug", "2013", "81"], ["Jul", "2013", "113"], ["Jun", "2013", "291"], ["Oct", "2013", "73"], ["Sep", "2013", "13"]]

为什么结果不按月和年排序?

我认为这个顺序是“按字母顺序”而不是日期..

4 个答案:

答案 0 :(得分:6)

我在Rails 5.0.1上执行此操作:

User.
where('created_at >= ? AND created_at <= ?', start, finish).
group('(EXTRACT(YEAR FROM created_at))::integer').
group('(EXTRACT(MONTH FROM created_at))::integer').
order('2 DESC, 3 DESC').count

产生这个:

{
  [2017, 2]=>1908,
  [2017, 1]=>5910,
  [2016, 12]=>6299,
  [2016, 11]=>5717,
  [2016, 10]=>5912,
  [2016, 9]=>6098,
  [2016, 8]=>5897,
  [2016, 7]=>5896,
  [2016, 6]=>5902,
  [2016, 5]=>6279,
  [2016, 4]=>5510,
  [2016, 3]=>5323,
  [2016, 2]=>5139,
  [2016, 1]=>4293
}

答案 1 :(得分:1)

我认为我当前的查询顺序是“按字母顺序”而不是日期..

to_char(date,'Mon')

这是按月和年分组查询,然后按月和年排序

ActiveRecord::Base.connection.select_rows("SELECT date_part('month', date), date_part('year', date), SUM(CASE WHEN Title = 4 THEN Qty ELSE 0 END) AS sold FROM Transactions WHERE Store_id = 5 AND Product_id = 2 GROUP BY date_part('month', date), date_part('year', date) ORDER BY date_part('month', date), date_part('year', date)")

结果如下:

←[1m←[36m (3.0ms)←[0m  ←[1m
SELECT date_part('month', date), date_part('year', date), SUM(CASE WHEN Title = 4 THEN Qty ELSE 0 END) AS sold FROM Transactions WHERE Store_id = 5 AND Product_id = 2 GROUP BY date_part('month', date), date_part('year', date) ORDER BY date_part('
month', date), date_part('year', date)
←[0m=> [["6", "2013", "291"], ["7", "2013", "113"], ["8", "2013", "81"], ["9", "2013", "13"], ["10", "2013", "73"]]

答案 2 :(得分:1)

用于Postgres的较新版本

看看本教程的示例E-> https://www.postgresqltutorial.com/postgresql-group-by/

您还需要在.group调用上添加函数:

    Model.select(
      "date_trunc('month', created_at)"
    ).group(
      "date_trunc('month', created_at)"
    )

虽然date_trunc似乎更快,但您也可以使用to_char对其进行分组,以便配置输出字符串:

    Model.select(
      "to_char(created_at, 'MM/YYYY')"
    ).group(
      "to_char(created_at, 'MM/YYYY')"
    )

在我的情况下,我添加了一个排序,一个计数,并且仅在select上调用to_char以获得更漂亮的结果:

    Order.select(
      <<-SQL
        to_char(date_trunc('month', created_at), 'MM/YYYY') AS month,
        COUNT(id) as number_of_orders
      SQL
    ).group(
      "date_trunc('month', created_at)"
    ).order(
      "date_trunc('month', created_at)"
    )

<<-SQL只是Heredoc

答案 3 :(得分:0)

此查询按月和年从transactions表组中获取数据,按ASC中的月顺序排列(如果不提及订单,则默认为

Transactions.select("DATE_TRUNC('month', date) AS month_year, SUM(CASE WHEN title = 4 THEN qty ELSE 0 END) AS sold").where("store_id = 5 AND product_id = 2").group("month_year")