【问题标题】:Find most recent row per user and day in sql query在sql查询中查找每个用户和日期的最新行
【发布时间】:2019-06-23 03:42:15
【问题描述】:

我想查找每个客户在每个日期的最近一次购买(客户可能在给定日期进行多次购买,我想要该日期的最近一次购买)。我的数据框如下所示:

Customer_id | Date                  | Payment  | Type
3             '2019-01-28 00:45:00'   128.93     Credit
2             '2019-01-26 01:00:00'    54.36     Debit
3             '2019-01-27 12:00:00'    93.99     Debit
3             '2019-01-28 03:15:00'   164.93     Credit
2             '2019-01-26 17:30:00'    56.74     Credit
2             '2019-01-28 19:15:00'    21.85     Credit

查询的输出应该给我类似以下的内容(我返回每个客户/日期组合的一行,并按客户/日期排序。我不关心类型 - 无论是信用卡还是借记):

Customer_id | Date          | Payment
2             '2019-01-26'    56.74
2             '2019-01-28'    21.85
3             '2019-01-27'    93.99
3             '2019-01-28'   164.93

到目前为止,这是我的代码:

SELECT
    R1.Customer_id,
    date_trunc('day', R1.Date),
    R1.Payment
FROM Records R1
WHERE R1.Date = (SELECT MAX(R2.Date)
                 FROM Records R2
                 WHERE R2.Customer_id = R1.Customer_id)
GROUP BY Customer_id, date_trunc('day', R1.Date);

我给出的示例是对我正在处理的数据和一些过滤条件的简化,但应该能捕捉到我面临的主要问题。不确定这是否在正确的轨道上,但是当我运行查询时,它似乎对“分组依据”不满意。我是 sql 新手,希望得到帮助!

【问题讨论】:

标签: sql postgresql group-by sql-order-by limit


【解决方案1】:

这个查询:

select Customer_id, Date::date, max(Date) maxdate from tablename group by customer_id, Date::date

获取每个客户的最近日期。
将其加入主表以获取包含每个客户最近日期的行:

select t.Customer_id, t.date, tt.Payment from (
select Customer_id, Date::date date, max(Date) maxdate from tablename group by customer_id, Date::date
) t inner join tablename tt
on tt.customer_id = t.customer_id and tt.date = t.maxdate

【讨论】:

  • 嗨!很抱歉,但我对问题描述进行了编辑,甚至提供了我编写的示例查询(未运行)。希望得到进一步的帮助和反馈。谢谢!
  • 查看我编辑的答案。 Date::date 表示仅将 Date 列转换为 date 而没有 time
  • 抱歉有点无知,但你能澄清tt.*ttt之间的区别吗?我假设 t 指的是 tablename 的第一个实例,而 tt 指的是第二个实例,但不确定 tt.* 是什么。
  • tt是主表的别名,所以tt.*表示主表的所有列t是子查询的别名跨度>
  • 对于 (1),请参阅我编辑的答案。对于 (2) 快速阅读:如果 R1.Payment 不包含在 group by 中,则不能选择它
【解决方案2】:

在 Postgres 中,distinct on 通常是最好的方法:

select distinct on (customer_id, date::date) t.*
from t
order by customer_id, date desc;

特别是,这可以利用(customer_id, date desc) 上的索引。

【讨论】:

  • 很抱歉投了反对票(不是我)。你介意解释你的答案吗?我不熟悉distinct on 方法。谢谢!
  • 另外,我更改了问题以更好地适应我正在解决的问题。我做了一个“虚拟”示例来突出我正在解决的问题,但最初并不是一个很好的示例。
  • @JaneSully 。 . .distinct on 仍然是最好的解决方案。
  • 你能解释一下为什么它是最好的解决方案吗?另外,我不完全理解查询是如何工作的?很想了解更多,如果我有更好的理解,我很乐意重新投票。谢谢!
  • @JaneSully 。 . .因为distinct on 通常对于此类查询具有最佳性能。
猜你喜欢
  • 2022-08-16
  • 2012-11-11
  • 1970-01-01
  • 2020-07-04
  • 1970-01-01
  • 1970-01-01
  • 2014-05-23
  • 2011-01-25
  • 2023-01-22
相关资源
最近更新 更多