我有以下查询:
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”值的行对应的所有列。
我试过这个,但它不起作用:
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)
这可以在一个复杂的查询中完成吗?
您可以使用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
)
旁注,我还会将“*”替换为您希望查询返回的实际字段列表。
我会这样做的查询:
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
从provnum
获得了provider_info
的独特值,每个都有最新的sourcedate
。
我们可以将结果加入provider_info
,并获得与provnum
匹配的行,并且有一个与sourcedate
匹配的latest_sourcedate
。
要排除行,我宁愿使用反连接模式而不是NOT IN。这种方式有效,我们进行外连接以查找prov_index
中的匹配行。 LEFT外连接将返回左侧的所有行,以及右侧的匹配。诀窍是在WHERE
子句中使用一个条件来排除找到匹配的行。连接谓词保证匹配的行将具有pi_provnum
的非NULL值。因此,如果我们排除具有非NULL值的行,即仅返回pi_provnum
为NULL值的行,那么我们剩下的是LEFT侧没有匹配的行。