按日期和其他列计算最后一个条目

Posted

技术标签:

【中文标题】按日期和其他列计算最后一个条目【英文标题】:Count last entry by date and other column 【发布时间】:2021-11-10 17:24:29 【问题描述】:

我目前正在处理一个统计页面,其中一张表格让我很吃力。

+----+-----------+----------+---------------------+
| id | id_status | id_queue | datetime            | // Comments
+----+-----------+----------+---------------------+
| 1  | 1         | 1        | 2021-07-01 17:03:13 | //<- last_entry: id_queue:1  for: #1#       (id_status: 1)
| 2  | 1         | 2        | 2021-07-01 17:03:18 | //<- last_entry: id_queue:2  for: #1#2#         (id_status: 1)
| 9  | 1         | 9        | 2021-07-01 17:03:45 |
| 10 | 1         | 10       | 2021-07-01 17:03:49 |
| 11 | 2         | 7        | 2021-07-01 17:04:10 |
| 12 | 3         | 7        | 2021-07-01 17:07:36 |
| 13 | 2         | 10       | 2021-07-01 17:07:54 |
| 14 | 3         | 10       | 2021-07-01 17:08:36 | //<- last_entry: id_queue:10 for: #1#       (id_status: 3)
| 15 | 2         | 9        | 2021-07-01 17:15:04 |
| 16 | 5         | 9        | 2021-07-01 17:15:24 | //<- last_entry: id_queue:9  for: #1#2#3#4# (id_status: 5)
| 18 | 3         | 7        | 2021-07-01 17:35:58 | //<- last_entry: id_queue:7  for: #1#       (id_status: 3)
//- -   -   -   - new day #2#  -    -   -   -   -   -   
| 19 | 2         | 7        | 2021-07-02 18:36:23 |
| 21 | 3         | 1        | 2021-07-02 18:39:49 |
| 22 | 14        | 1        | 2021-07-02 18:40:17 |
| 23 | 14        | 10       | 2021-07-02 18:40:17 |
| 24 | 2         | 1        | 2021-07-02 19:14:21 |
| 25 | 1         | 1        | 2021-07-02 19:14:32 | //<- last_entry: id_queue:1  for: #2#3#4#   (id_status: 1)
| 26 | 2         | 10       | 2021-07-02 19:14:35 |
| 27 | 1         | 10       | 2021-07-02 19:14:39 | //<- last_entry: id_queue:10 for: #2#3#4#   (id_status: 1)
| 28 | 1         | 7        | 2021-07-02 19:14:46 | //<- last_entry: id_queue:7  for: #2#3#4#   (id_status: 1)
//- -   -   -   - new day #3#  -    -   -   -   -   -   
| 31 | 2         | 2        | 2021-07-05 17:20:39 |
| 32 | 3         | 2        | 2021-07-05 17:24:59 | //<- last_entry: id_queue:2  for: #3#       (id_status: 3)
//- -   -   -   - new day #4#  -    -   -   -   -   -   
| 33 | 2         | 3        | 2021-07-06 09:38:03 |
| 34 | 3         | 3        | 2021-07-06 09:38:16 | //<- last_entry: id_queue:3  for: #4#       (id_status: 3)
| 35 | 2         | 6        | 2021-07-06 10:12:18 | //<- last_entry: id_queue:6  for: #4#       (id_status: 2)
| 37 | 2         | 2        | 2021-07-06 11:37:50 |
| 38 | 13        | 2        | 2021-07-06 12:02:19 |
| 39 | 2         | 2        | 2021-07-06 12:02:21 |
| 40 | 13        | 2        | 2021-07-06 12:04:12 | //<- last_entry: id_queue:2  for: #4#       (id_status: 13)
+----+-----------+----------+---------------------+

我希望从每个 id_queue 中获取每个 %Y/%m/%d 直到当前 id_status 日期的每个最后条目的 COUNT。

基本上,对于每一天,它都会根据实际的datetime 列计算最后一个条目。

基于上表的输出示例:

+-----------+--------------+------------+-------------------------------------------+
| id_status |  occurrences |  day       |  HELP_COLUMN(comment id from table above) |
+-----------+--------------+------------+-------------------------------------------+
| 1         | 2            | 2021-07-01 |  #1#                                      |
| 3         | 2            | 2021-07-01 |  #1#                                      |
| 5         | 1            | 2021-07-01 |  #1#                                      |
| 2         | 4            | 2021-07-02 |  #2#                                      |
| 5         | 1            | 2021-07-02 |  #2#                                      |
| 1         | 3            | 2021-07-05 |  #3#                                      |
| 3         | 1            | 2021-07-05 |  #3#                                      |
| 5         | 1            | 2021-07-05 |  #4#                                      |
| 1         | 3            | 2021-07-05 |  #4#                                      |
| 3         | 1            | 2021-07-05 |  #4#                                      |
| 2         | 1            | 2021-07-05 |  #4#                                      |
| 13        | 1            | 2021-07-05 |  #4#                                      |
+-----------+--------------+------------+-------------------------------------------+
对于 #1#(第一天),获取 id_queue 的最后一个条目(基于 最大值(日期时间)。 对于#2#(第二天),获取 id_queue 的最后一个条目 (基于 max(datetime))(你可以看到一些最后的条目 id_queue 在前一天)。等等……

我尝试了多种方法,但我开始觉得这看起来需要使用迭代器来解决...但我无法每天执行一个 SQL 查询,这会花费太多性能。

有人知道我可以使用哪个 SQL 请求吗? 坦克。


编辑:这是另一个例子:

输入:

+-----+-----------+----------+---------------------+
| id  | id_status | id_queue |      datetime       |
+-----+-----------+----------+---------------------+
|  61 |         5 |        1 | 2021-07-01 15:03:40 |
| 132 |         5 |        1 | 2021-07-01 16:39:13 |
|   1 |         1 |        1 | 2021-07-01 17:03:13 | <- last 1 :    1 #1#
|   2 |         1 |        2 | 2021-07-01 17:03:18 | <- last 2 :    1 #1#2#
|   3 |         1 |        3 | 2021-07-01 17:03:21 | <- last 3 :    1 #1#2#
|   4 |         1 |        4 | 2021-07-01 17:03:25 | <- last 4 :    1 #1#2#3#
|   5 |         1 |        5 | 2021-07-01 17:03:29 | <- last 5 :    1 #1#2#3#
|   6 |         1 |        6 | 2021-07-01 17:03:33 | <- last 6 :    1 #1#2#3#
|   7 |         1 |        7 | 2021-07-01 17:03:37 | 
|   8 |         1 |        8 | 2021-07-01 17:03:41 | <- last 8 :    1 #1#2#3#
|   9 |         1 |        9 | 2021-07-01 17:03:45 | 
|  10 |         1 |       10 | 2021-07-01 17:03:49 |
|  11 |         2 |        7 | 2021-07-01 17:04:10 |
|  12 |         3 |        7 | 2021-07-01 17:07:36 |
|  13 |         2 |       10 | 2021-07-01 17:07:54 |
|  14 |         3 |       10 | 2021-07-01 17:08:36 | <- last 10 :   3 #1#
|  15 |         2 |        9 | 2021-07-01 17:15:04 |
|  16 |         5 |        9 | 2021-07-01 17:15:24 | <- last 9 :    5 #1#2#3#
|  17 |         2 |        7 | 2021-07-01 17:35:36 |
|  18 |         3 |        7 | 2021-07-01 17:35:58 | <- last 7 :    3 #1#
|  19 |         2 |        7 | 2021-07-02 18:36:23 |
|  20 |         2 |        1 | 2021-07-02 18:36:39 |
|  21 |         3 |        1 | 2021-07-02 18:39:49 |
|  23 |        14 |       10 | 2021-07-02 18:40:17 |
|  22 |        14 |        1 | 2021-07-02 18:40:17 |
|  24 |         2 |        1 | 2021-07-02 19:14:21 |
|  25 |         1 |        1 | 2021-07-02 19:14:32 | <-- last 1 :   1 #2#3#
|  26 |         2 |       10 | 2021-07-02 19:14:35 |
|  27 |         1 |       10 | 2021-07-02 19:14:39 | <-- last 10 :  1 #2#3#
|  28 |         1 |        7 | 2021-07-02 19:14:46 | <-- last 7 :   1 #2#3#
|  29 |         2 |        3 | 2021-07-05 15:26:27 |
|  30 |         3 |        3 | 2021-07-05 15:26:48 | <--- last 3 :  3 #3#
|  31 |         2 |        2 | 2021-07-05 17:20:39 |
|  32 |         3 |        2 | 2021-07-05 17:24:59 | <--- last 2 :  3 #3#
+-----+-----------+----------+---------------------+

#1 (2021-07-01):

1,1,1,1,1,1,1(7 次出现) 3,3(2 次出现) 5(1 次)

#2 (2021-07-02): : https://i.ibb.co/vDhL05q/sublime-text-or-MEzs-GFh-Q.jpg

1,1,1,1,1,1,1,1,1(9 次出现) 5(1 次)

#3 (2021-07-05):

1,1,1,1,1,1,1(7 次出现) 3,3(2 次出现) 5(1 次)

输出:

+-----------+-------------+------------+
| id_status |  occurences |     day    |
+-----------+-------------+------------+
|         1 |           7 | 2021-07-01 |
|         3 |           2 | 2021-07-01 |
|         5 |           1 | 2021-07-01 |
|         1 |           9 | 2021-07-02 |
|         5 |           1 | 2021-07-02 |
|         1 |           7 | 2021-07-05 |
|         3 |           2 | 2021-07-05 |
|         5 |           1 | 2021-07-05 |
+-----------+-------------+------------+

【问题讨论】:

【参考方案1】:
select date(datetime) as day, id_status, count(*) as occurrences
from (
  select *,row_number() over (partition by date(datetime),id_queue order by datetime desc) rn 
  from tablename
) t where rn = 1
group by date(datetime) , id_status
order by date(datetime) , id_status

此查询对同一 id_queue 的每一天中的行进行排序,并首先按最新的行号排序并选择第一个 (rn = 1),因此您每天都有最新的唯一 id_queue,然后您按并计算queu_ids的数量

【讨论】:

你好@eshirvana,谢谢你的回答,你能详细说明它是如何工作的吗?仍然存在问题,缺少条目。我在我的桌子上测试了它:第一天总计 => 10(不同 id_queue 的数量)但第二天只有 3 个存在。 @MathiasOsterhagen 嗯....应该可以的。对于您提供的数据样本,它有效。编辑您的问题和此查询不起作用的数据,并为他们显示您的预期输出 我刚刚更新了我的问题。再次感谢您帮助我,在您的查询中,我遗漏了几行(结果如下:@eshirvana,我刚刚更新了我的问题。根据您的查询,我遗漏了几行(结果如下:pastebin.com/raw/kLPcfJkU) @MathiasOsterhagen 第 2 天(2021-07-02),所有选定的 id_queue 都有 id_status =1 ,为什么在输出中有 id_status = 5 ?即使对于 id_status = 1,那一天的发生次数是 3 次,为什么是 9 次?我没有遵循你的逻辑 你好@eshirvana。检查line 16,您会看到#2#id_status = 5。实际上,您拥有它九次,因为它从一开始就很重要。喜欢&lt;= current_date。要计算它,您从底部开始,然后将当天的出现标记为 #1 或 #2,以使其清除,将其复制粘贴到文本编辑器中,如 sublime text 并像这样搜索 #2:i.ibb.co/vDhL05q/sublime-text-or-MEzs-GFh-Q.jpg。这就像每天从datetime &lt;= current day 获取最后一个条目。感谢您的帮助【参考方案2】:

我写这个查询成功了:

我确信它可以优化并且可以减少到更少的子查询,如果有人有想法,我很乐意选择另一个答案作为“解决答案”

SELECT id_status, COUNT(entries_status.id_status) as occurrences, entries_status.day
FROM (
    SELECT history.id_status, history.id_queue, last_entries.day
    FROM history
    INNER JOIN(
        SELECT id_queue, max(datetime) last_entry_of_day, day
        FROM (
            SELECT *
            FROM history
            LEFT JOIN (
                SELECT date(datetime) AS day
                FROM `history`
                GROUP BY date(datetime)) as days
                ON date(history.datetime) <= days.day
                ORDER BY datetime ASC) entries
            GROUP BY id_queue, day
    ) as last_entries
    ON history.id_queue = last_entries.id_queue AND
history.datetime = last_entries.last_entry_of_day) as entries_status
GROUP BY entries_status.day, entries_status.id_status

【讨论】:

以上是关于按日期和其他列计算最后一个条目的主要内容,如果未能解决你的问题,请参考以下文章

Rank() 基于列条目,而数据按日期排序

如何在 MongoDB 中按日期分组

为每行和 id mysql 附加最后 3 个日期条目

如何计算 SQL Server 中按日期和用户分组的条目之间的平均时间?

Pandas:按第一次和最后一次出现填充每一行

将条目数据发布到 html 表行