SQL 嵌套查询和使用 MAX 提取最近的事务和/或评论

Posted

技术标签:

【中文标题】SQL 嵌套查询和使用 MAX 提取最近的事务和/或评论【英文标题】:SQL nested query and use of MAX to extract most recent transaction and/or comment 【发布时间】:2020-11-04 10:59:43 【问题描述】:

我们有一个记录客户 cmets (ARCMM) 的 SQL 数据库表。我想提取每个客户的最新评论。一些客户没有任何 cmets(即 ARCMM 中没有条目)。 客户的最新评论将具有最近的日期(字段 DATEENTR),并且对于该日期,字段 CNTUNIQ 的最高值。下面的查询没有按预期工作。最好的解决方法?

查询:

SELECT
----- Customer masterfile
[ARCUS].[IDCUST],
[ARCUS].[NAMECUST],
----- Customer comments
[ARCMM].[CNTUNIQ],
[ARCMM].[DATEENTR],
[ARCMM].[TEXT]
FROM
[ARCUS]  
----- Table ARCMM roto ID AR0021  Customer Comments -----
   LEFT JOIN [ARCMM]
   ON
   [ARCMM].[IDCUST] = [ARCUS].[IDCUST]
   AND
   [ARCMM].[CNTUNIQ] =              
                  (  
                   SELECT MAX([CNTUNIQ])
                   FROM [ARCMM] ARCMMcopy2
                   WHERE 
                   [ARCMMcopy2].[IDCUST] = [ARCMM].[IDCUST]   
                   AND
                   [ARCMM].[DATEENTR] =  
                                       (
                                        SELECT MAX([DATEENTR])    
                                        FROM [ARCMM] ARCMMcopy1
                                        WHERE
                                        [ARCMMcopy1].[IDCUST]  = [ARCMM].[IDCUST]
                                        )
                   )    

示例表 ARCMM 数据:

IDCUST  DATEEENTR  CNTUNIQ  TEXT
Bob     20200311        1   Bob has woken up
Bob     20200311        2   Bob is having breakfast
Bob     20200629        1   Bob is sleeping         <most recent for IDCUST Bob
Jill    20200128        1   Order started
Jill    20200218        1   Order sent
Jill    20200218        2   Goods received
Jill    20200218        3   Goods counted
Jill    20200325        1   Invoice received
Jill    20200325        2   Invoice processed       <most recent for IDCUST Jill
Alison  20200225        1   Swimming
Alison  20200425        1   Walking
Alison  20200425        2   Running
Alison  20200425        3   Running
Alison  20200425        4   Sprinting
Alison  20200425        5   Jogging
Alison  20200425        6   Stopped                 <most recent for IDCUST Alison

我的 SQL 查询尝试的结果:

IDCUST   NAMECUST          CNTUNIQ   DATEENTR   TEXT
Bob      Bob Brown         Null      Null       Null
Jill     Jill Jenkins      Null      Null       Null
Alison   Alison Allpress   6         20200425   Stopped 

期望的结果:

IDCUST   NAMECUST          CNTUNIQ   DATEENTR   TEXT
Bob      Bob Brown         1         20200629   Bob is sleeping
Jill     Jill Jenkins      2         20200325   Invoice processed
Alison   Alison Allpress   6         20200425   Stopped 

【问题讨论】:

感谢戈登编辑 【参考方案1】:

如果您的数据库支持窗口函数,您可以在left join 中使用row_number()

SELECT
    c.[IDCUST],
    c.[NAMECUST],
    m.[CNTUNIQ],
    m.[DATEENTR],
    m.[TEXT]
FROM [ARCUS] c 
LEFT JOIN (
    SELECT 
        m.*, 
        ROW_NUMBER() OVER(
            PARTITION BY [IDCUST] 
            ORDER BY [DATEENTR] DESC, [CNTUNIQ] DESC
        ) rn
    FROM [ARCMM] m
) m ON m.[IDCUST] = c.[IDCUST] and m.rn = 1

【讨论】:

这是否允许在一个日期输入多个 TEXT? SELECT 语句如何为最近的 DATEENTR 选择具有最高 CNTUNIQ 的条目? @AndrewTaggart:我们在order by 子句中需要另一个标准。我刚刚添加了它。 感谢 GMB - 您的回答解决了我的问题。使用 PARTITION 对我来说是新的 - 我最好做一些阅读!

以上是关于SQL 嵌套查询和使用 MAX 提取最近的事务和/或评论的主要内容,如果未能解决你的问题,请参考以下文章

Django中的聚合/分组查询/F/Q查询/orm执行原生sql语句/ ORM事务和锁

SQL:从记录中提取最近添加的日期

SQL 嵌套事务

SQL高级查询:嵌套和分页

如何获取 SQL 中具有 MAX 和 MIN 值的行的 ID

TransactionScope:具有不同数据库连接的嵌套事务(SQL Server 和 Postgresql)