将在分组结果中获取最新行的嵌套查询
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数据库(中)分组,嵌套,连接查询及外键与关系表设计