将在分组结果中获取最新行的嵌套查询

Posted

技术标签:

【中文标题】将在分组结果中获取最新行的嵌套查询【英文标题】:Nested query that will fetch latest row in grouped result 【发布时间】:2018-08-03 23:25:43 【问题描述】:

我有以下疑问:

 SELECT * from `provider_info` where provnum not in 
 (select pi_provnum from prov_index where length(pi_provnum)=6)
 and length(provnum)=6 group by provnum

prov_index 每个 provnum/pi_provnum 只有一行。但是 provider_info 每个省可以有多行。

我基本上是从一个表中提取第二个表中没有提供者 (provnum/pi_provnum) 条目的行。内部查询为我提供了 provnum 列的列表,这些列存在于 provider_info 表中,但不存在于 prov_index 表中。 (length() 条件是我在查询中需要的额外内容)

由于 provider_info 中可能有多个具有相同 provnum 的条目,我使用“group by provnum”子句只给我一个实例。但我最终需要与具有最新 'sourcedate' 值的行对应的所有列。

    有没有办法使用 DISTINCT 代替 GROUP 子句?

    最终,我需要从 provider_info 返回一个特定的行(所有列),即“soucedate”列中具有最新日期的行

我试过了,但它不起作用:

 SELECT * from `provider_info` where provnum not in 
 (select pi_provnum from prov_index where length(pi_provnum)=6) 
 and length(provnum)=6 order by provnum,sourcedate desc group by provnum 
 having sourcedate=max(sourcedate)

基本上,我想要的是 provider_info 中的一行列表,其中包含最新的 sourcedate 列,其中 provnum 在第二个表 prov_index 中不存在。关键是我想要最后一行中的所有列,而不仅仅是 max(sourcedate)

这可以在单个复杂查询中完成吗?

【问题讨论】:

您也许可以使用 order by 和 limit 作为过滤器... Select * from provider_info order by sourcedate limit 1 见meta.***.com/questions/333952/… groupwise max 【参考方案1】:

您可以使用 NOT EXISTS 子句。如果您在 provider_info 和相同的 sourcedate(即最新日期)中有相同 provnum 的两条记录,则它可能会返回重复的行。如果这在您的场景中是不可能的,或者在这种情况下您想要两行,这可能会起作用:

SELECT p1.* 
from `provider_info` p1 where p1.provnum not in 
(select pi_provnum from prov_index where length(pi_provnum)=6) 
and length(p1.provnum)=6
AND NOT EXISTS (
    SELECT * FROM provider_info p2 where p1.provnum = p2.provnum AND p1.sourcedate > p2.sourcedate 
)

旁注,我还将用您希望查询返回的实际字段列表替换“*”。

【讨论】:

谢谢 - 我将对此进行测试并报告! :)【参考方案2】:

我会这样查询:

 SELECT p.*
   FROM
        ( -- latest sourcedate for each provnum
          SELECT s.provnum
               , MAX(s.sourcedate) AS latest_sourcedate
            FROM `provider_info` s
           WHERE LENGTH(s.provnum) = 6
           GROUP
              BY s.provnum
        ) q

     -- row(s) that matches latest sourcedate
   JOIN `provider_info` p
     ON LENGTH(p.provnum) = 6
    AND p.provnum         = q.provnum
    AND p.sourcedate      = q.latest_sourcedate

     -- anti-join exclude rows that have a match
   LEFT
   JOIN prov_index i
     ON LENGTH(i.pi_provnum) = 6
    AMD i.pi_provnum = p.provnum
  WHERE i.pi_provnum IS NULL

  ORDER BY ...

让我们稍微解开一下。

内联视图(派生表)q 为我们提供与 provider_info 不同的 provnum 值,每个值都有最新的 sourcedate

我们可以将该结果连接到provider_info,并获取与provnum 匹配的行,并拥有与latest_sourcedate 匹配的sourcedate

要排除行,我更喜欢使用反连接模式而不是 NOT IN。这样做的方式是,我们执行 outer 连接以从 prov_index 中查找匹配的行。 LEFT 外连接将返回左侧的所有行以及右侧的匹配项。诀窍是在WHERE 子句中使用一个条件,排除 找到匹配的行。连接谓词向我们保证匹配的行将具有pi_provnum 的非NULL 值。因此,如果我们排除具有非 NULL 值的行,即仅返回 pi_provnum 为 NULL 值的行,我们剩下的就是左侧没有匹配的行。

【讨论】:

以上是关于将在分组结果中获取最新行的嵌套查询的主要内容,如果未能解决你的问题,请参考以下文章

Java学习总结(十六)——MySQL数据库(中)分组,嵌套,连接查询及外键与关系表设计

流分析 - 查询嵌套数组返回 0 个结果

在嵌套选择查询中按条件分组后加入

SQL Server 查询以根据用户提供的 id 获取嵌套的子记录

用于迭代嵌套结果的 Django 查询集预取优化

有没有办法将 GraphQL 查询字段分组到子/嵌套查询组中?