【问题标题】:How to edit my postgreSQL query to select the most recent row by date for several columns如何编辑我的 postgreSQL 查询以按日期选择几列的最新行
【发布时间】:2021-01-17 16:27:49
【问题描述】:

我有一个查询,我试图根据日期选择最近的行。所以我希望我的查询做的是为我的数据库中的几列选择最新的数据点。

sql = f"""SELECT DISTINCT ON (id), cast(marketcap as money), cast(week52high as money), cast(week52low as money)
                 , to_char(dividend_yield * 100, '99D99%%')
                 , pe_ratio, ROUND(beta,2) 
          FROM security_stats 
          WHERE security_stats.id IN ({placeholders});
       """

对于任何想知道的人,placeholders 只是用户给出的股票列表。

此应用程序的目标是检索财务数据点的最新观察结果。我的查询工作正常,但是当我只想要每只股票的最新行时,它会选择每只股票的所有行。

如何编辑我的查询以解决上述问题?我尝试了一些使用MAXLIMIT 的方法,但无法正常工作!

编辑: 请注意,使用的列是 iddate。这些应该是不同的,并且日期应该是最近的观察。

感谢@GME,使用下面的这个方法让它工作。也特别感谢@Somy 也向我展示了另一种方法!

sql = f"""SELECT DISTINCT ON (id) id, cast(marketcap as money), cast(week52high as money), cast(week52low as money)
                 , to_char(dividend_yield * 100, '99D99%%')
                 , pe_ratio, ROUND(beta,2) 
          FROM security_stats 
          WHERE security_stats.id IN ({placeholders}) ORDER BY id, date desc ;
       """

【问题讨论】:

  • 哪一列存储stock?哪一个定义了最近的行?
  • 完全忘了补充,太傻了。我使用id 列作为股票名称,使用date 列作为日期。我更新了我的 OG 帖子以反映我使用底部建议的新尝试

标签: python sql postgresql sql-order-by greatest-n-per-group


【解决方案1】:

distinct on 子句中的列(或列集)定义了组:如果您希望每个“股票”有一行,那么列 stock 应该属于该子句。

然后,您需要一个order by:它以distinct on 列开头,然后是一个或多个列,用于定义应在每个组中保留哪一行:这是“日期”列所在的位置.

您的问题没有解释表中关键列的名称是什么。假设我们有iddate,逻辑是:

SELECT DISTINCT ON (id) ...
FROM security_stats 
WHERE ...
ORDER BY id, date desc 

【讨论】:

    【解决方案2】:

    假设 id 列是等效于 stock 的键列(如问题中所述)-您可以使用以下 windows 功能-

    sql = f"""SELECT DISTINCT id, cast(marketcap as money), cast(week52high as money), cast(week52low as money)
                     , to_char(dividend_yield * 100, '99D99%%')
                     , pe_ratio, ROUND(beta,2)
              from 
              (Select t.*, 
                     row_number() over(partition by id order by date desc) as seq_num  
                   FROM security_stats t
                   WHERE t.id IN ({placeholders})) sst
              WHERE sst.seq_num = 1;
           """
    

    【讨论】:

    • 是的,我意识到并编辑了它。错过了 from 子句,刚才又做了一次编辑。请立即尝试。
    • @Dre - 我做了一些代码更正。如果您可以在我的回复中重新尝试使用最新的代码,那就太好了。
    • 我认为 GME 的另一个建议是基于“DISTINCT ON”,我猜你也在尝试。 “DISTINCT ON”是 PostgreSQL 独有的。我的方法基于 Windows 函数,它在 RDBMS 中更通用 btw @GMB 本人是 Windows 函数的大师,但可能他试图用你在代码中尝试的方法来解决它。
    • @Dre:你只能接受一个答案(但你可以upvote任意多)。请参阅:stackoverflow.com/help/someone-answers
    • 对 Dre & GMB 造成的混乱感到抱歉。 @Dre - 来回抱歉,我不知道这一点。如果可以接受 GMB 的回答,那就太好了,因为这就是您正在使用的。谢谢!!
    猜你喜欢
    • 2012-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多