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

问题描述 投票:0回答:2

我有以下查询:

 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可以有多行。

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

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

  1. 有没有办法使用DISTINCT而不是GROUP子句?
  2. 最后,我需要从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)

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

mysql sql mariadb greatest-n-per-group
2个回答
0
投票

您可以使用NOT EXISTS子句。如果您在provider_info中有相同的provnum和相同的sourcedate(最新日期),则它有一个可以返回重复行的情况。如果在您的方案中不可能,或者在这种情况下您想要两个行,这可能有效:

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 
)

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


0
投票

我会这样做的查询:

 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 ...

让我们解开一下。

内联视图(派生表)qprovnum获得了provider_info的独特值,每个都有最新的sourcedate

我们可以将结果加入provider_info,并获得与provnum匹配的行,并且有一个与sourcedate匹配的latest_sourcedate

要排除行,我宁愿使用反连接模式而不是NOT IN。这种方式有效,我们进行外连接以查找prov_index中的匹配行。 LEFT外连接将返回左侧的所有行,以及右侧的匹配。诀窍是在WHERE子句中使用一个条件来排除找到匹配的行。连接谓词保证匹配的行将具有pi_provnum的非NULL值。因此,如果我们排除具有非NULL值的行,即仅返回pi_provnum为NULL值的行,那么我们剩下的是LEFT侧没有匹配的行。

© www.soinside.com 2019 - 2024. All rights reserved.