【问题标题】:Group By records based on start date and end date with count Rails基于开始日期和结束日期的分组依据记录与计数 Rails
【发布时间】:2017-05-30 09:58:59
【问题描述】:

假设是 2017 年 5 月,我想获取 2017 年 4 月的记录。

我的查询使用计数获取 2017 年 4 月的记录,但我也想包括空日期。

因此,所需的输出将是:

----------------------
id | date     | count
----------------------
1  | 01/04/17 |  0    // 0 because this dates does not have any tickets.
2  | 02/04/17 |  0    // 0 because this dates does not have any tickets.
3  | 03/04/17 |  0    // 0 because this dates does not have any tickets.
4  | 04/04/17 |  0    // 0 because this dates does not have any tickets.
5  | 05/04/17 |  0    // 0 because this dates does not have any tickets.
6  | 06/04/17 |  0    // 0 because this dates does not have any tickets.
7  | 07/04/17 |  0    // 0 because this dates does not have any tickets.
8  | 08/04/17 |  0    // 0 because this dates does not have any tickets.

直到30/04/2017

15/04/17 显示 2 个计数,因为它包含 2 条记录,而我的查询也表明了这一点 但 如何从01/04/17 - 30/04/2017 开始包含空日期

查询是:

Ticket.includes(:line_items).where('tickets.created_at > ? AND 
tickets.created_at < ?', Date.today.last_month.beginning_of_month, 
Date.today.beginning_of_month).where.not(line_items: {id: nil}).count

输出是:

SELECT COUNT(DISTINCT "tickets"."id") FROM "tickets" LEFT OUTER JOIN 
"line_items" ON "line_items"."ticket_id" = "tickets"."id" WHERE 
(tickets.created_at > '2017-04-01' AND tickets.created_at < '2017-05-01') AND 
("line_items"."id" IS NOT NULL)

所需的输出应显示如下记录:

同样,如果用户选择过去 7 天,它也应该显示过去 7 天的记录。

有什么办法可以解决吗?

【问题讨论】:

  • 这是 pgsql 还是 mysql?
  • 你的问题不清楚:你想要每天创建的票数吗?为什么你还有line_items
  • @ŁukaszKamiński 它的 postgres
  • @coorasse line_items 用于查看工单的行项目是否存在。如果票证中包含line_items,则该票证被视为最终票证。我想计算包含 line_items 的四月每一天的票数。这有意义吗?
  • 如果您将问题一分为二,也许您更有可能得到答案——因为现在您正在寻找具有 pgsql 和 RoR 知识的人。您的 pgsql 问题很容易回答,我相信 RoR 部分也适合有编码经验的人。

标签: mysql ruby-on-rails postgresql ruby-on-rails-4


【解决方案1】:

假设您将用户输入存储在名为“no_of_days”的变量中。你可以做类似的事情

data = Ticket.includes(:line_items).where('tickets.created_at > ? AND tickets.created_at < ?', Time.now.beginning_of_day - (no_of_days).days , Time.now.beginning_of_day).where.not(line_items: {id: nil}) #retrieves all data in a single query

(0..no_of_days).map do |day_from_now|
  todays_data = data.select{|item| item.created_at < (Time.now.beginning_of_day - (day_from_now).days) && item.created_at > (Time.now.beginning_of_day - (day_from_now - 1).days)}
 return { "day": (Date.today - day_from_now.days).strftime("%A %d-%m"), 
  "ticket_count": todays_data.size, 
  "total_sales": todays_data.inject(0){|sum, item| sum + item.line_item.quantity * item.line_item.rate }
end

【讨论】:

  • 如果您能更多地了解用户的选择,那就太好了。我假设用户有last week =&gt; number of days = 7last month =&gt; number of days = 30last 2 months =&gt; number of days = 60last year =&gt; number of days = 365 等选项。
  • 你的代码也给了我这样的错误:syntax error, unexpected ':', expecting keyword_end day: Date.today - day_from_now.days, ^ (irb):54: syntax error, unexpected ',', expecting keyword_end day: Date.today - day_from_now.days,
  • 请原谅我的语法错误。我已经更新了我的答案。这应该给出一些有意义的东西。我在循环中添加了花括号,因为它每天都返回一个哈希(键值对)。我只在这里返回天数和 item_count。我不确定您屏幕截图中的第三列。
  • 第二列是该特定日期的票数。意思是我的截图:01/04/17 - 2 (tickets in 01/04/17 from ticket table) - $800 (total sales of these 2 tickets means from line_items table: {line_item.count * line_item.quantity} 这有意义吗?
  • 编辑了我的答案以包括总销售额。结果将返回一个哈希数组。您可以将其包含在视图中以显示表格数据。
【解决方案2】:

SQL-Server 中,您可以通过以下方式实现:

DECLARE @MinDate DATE = '20170401',
        @MaxDate DATE = '20170430';
SELECT t.Id, d.[Date], COALESCE(t.[Count],0) AS [Count]
FROM (
SELECT  TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
        Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate)
FROM    sys.all_objects a
        CROSS JOIN sys.all_objects b
) d
LEFT JOIN yourTbl AS t ON d.Date = t.Date

【讨论】:

  • 我正在使用 Rails + Postgres。这在 Rails 中是否会以同样的方式工作?
【解决方案3】:

回答 PostgreSQL,但不回答 RoR,因为我不知道:

SELECT dat::date, count(DISTINCT tic."id")
  FROM generate_series('2017-04-01'::date, '2017-04-30'::date, interval '1 day') AS dat
  LEFT JOIN (SELECT "tickets"."id", "tickets"."created_at"
               FROM "tickets"
               JOIN "line_items"
                 ON "line_items"."ticket_id" = "tickets"."id") tic
  ON tic."created_at" = dat::date
 GROUP BY dat
 ORDER BY dat

SELECT dat::date, count(DISTINCT "tickets"."id")
  FROM generate_series('2017-04-01'::date, '2017-04-30'::date, interval '1 day') AS dat
  LEFT JOIN "tickets" ON "tickets"."created_at" = dat::date
                     AND EXISTS(SELECT 1 FROM "line_items"
                                 WHERE "line_items"."ticket_id" = "tickets"."id" LIMIT 1)
 GROUP BY dat
 ORDER BY dat

generate_series 创建从param1param2 的行集,间隔为param3

【讨论】:

    猜你喜欢
    • 2022-01-22
    • 2022-01-23
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    相关资源
    最近更新 更多