【问题标题】:Finding Max(Date) BEFORE specified date in Redshift SQL在 Redshift SQL 中查找指定日期之前的 Max(Date)
【发布时间】:2021-01-27 07:09:28
【问题描述】:

我在 SQL (AWS Redshift) 中有一个表(表 A),我在其中隔离了包含帐户 ID 和日期的初始总体。我想将该表的输出和 LEFT 连接回“帐户”表,以仅返回在我的输出中存储在表中的日期之前或之前的开始日期。

Table A (Beg Pop)
-------
select account_id, 
min(start_date),  
min(end_date)
from accounts
group by 1;

我只想返回当前表中 account_id 匹配的日期之前的日期。我正在寻找类似...

Table B
-------
select a.account_id,  
a.start_date,  
a.end_date,
b.start_date_prev,
b.end_date_prev
from accounts as a
left join accounts as b on a.account_id = b.account_id
where max(b.start_date) less than a.start_date;

最终,我想返回表 a 中的所有内容,并且只返回 max(start_date) 小于表 A 中 start_date 的日期。我知道 WHERE 子句中不允许聚合,我想我可以做一个子查询,但是我只想要输出中的日期之前的最大日期。非常感谢任何建议。

【问题讨论】:

  • 样本数据和期望的结果会有很大帮助。
  • 日期如何早于开始日期,即帐户的最短日期?
  • 我将添加示例数据和所需结果,但开始日期是我根据业务规则参数选择的,因此从某种意义上说它不是开始日期,而是真正的开始日期。在这个用例中,有一些日期在“start_date”之前。由于没有更好的名称,我只是将其标记为。 @GordonLinoff

标签: sql subquery amazon-redshift aggregate-functions


【解决方案1】:

据我了解,要求是显示基表中的所有行,其中前面的数据基于列和某些条件进行排序

请查看我从文章Select Next and Previous Rows with Current Row using SQL CTE Expression中获取的以下示例

WITH CTE as (
  SELECT
    ROW_NUMBER() OVER (PARTITION BY account_id ORDER BY start_date) as RN,
    *
  FROM accounts
)
SELECT
  PreviousRow.*,
  CurrentRow.*,
  NextRow.*
FROM CTE as CurrentRow
LEFT JOIN CTE as PreviousRow ON
  PreviousRow.RN = CurrentRow.RN - 1 and PreviousRow.account_id = CurrentRow.account_id
LEFT JOIN CTE as NextRow ON
  NextRow.RN = CurrentRow.RN + 1 and NextRow.account_id = CurrentRow.account_id
ORDER BY CurrentRow.account_id, CurrentRow.start_date;

我使用以下示例数据进行了测试,它似乎可以正常工作

create table accounts(account_id int, start_date date, end_date date);

insert into accounts values (1,'20201001','20201003');
insert into accounts values (1,'20201002','20201005');
insert into accounts values (1,'20201007','20201008');
insert into accounts values (1,'20201011','20201013');
insert into accounts values (2,'20201001','20201002');
insert into accounts values (2,'20201015','20201016');

输出如下

【讨论】:

    【解决方案2】:

    我只想返回当前表中 account_id 匹配的日期之前的日期

    如果您想要给定行的上一个日期,请使用lag()

    select a.*,
           lag(start_date) over (partition by account_id order by start_date) as prev_start_date
    from accounts a;
    

    【讨论】:

    • 这也很有帮助。我试图首先隔离我的初始种群,而不是仅仅按照您的建议进行操作并在此窗口函数步骤之后进行聚合。谢谢。
    猜你喜欢
    • 2015-12-10
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    • 2018-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多