(Advantage数据库服务器)我有一个服务提供程序的表,为了审计的目的,从不删除。他们有一个开始日期和结束日期;在名称或地址等更改的情况下,现有的行将结束日期,创建新行,并为已更改的数据分配新的开始日期。匹配存在多个JOIN的只有一个特定的行
在处理向这些提供商付款的过程中,我需要一个汇总页面,其中列出了提供商名称,地址,标识符(ProvID)以及支付的总金额。这是通过一个SUM()和GROUP BY的相当直接的查询完成的。
当指定提供程序标识符有两行或更多行时,会出现此问题。我最终得到重复的行(如果没有被捕获,可能会导致对该提供者的多次付款)。
我首先想到的是使用的东西(难看,但表现相当快)就像一个子查询:
SELECT ... FROM service s
INNER JOIN provider p ON p.ProvID = s.ProvID
AND (p.EndDate IS NULL or p.EndDate = (SELECT Max(EndDate) FROM
provider lu WHERE lu.ProvID = s.ProvID))
不幸的是,这仍然最终找到两行;一行为NULL EndDate,另一行为MAX(EndDate)。
我处理这个问题在其他情况下(如,定位为提供在特定日期服务的正确ProvID)使用
p.EndDate is null or (s.ServiceDate BETWEEN p.StartDate AND p.EndDate)
不幸的是,因为这个问题的查询是一组由一个总的服务日期不可用。
有什么建议吗?
编辑:我正在寻找的是要么是NULL EndDate行,如果它存在,或者与最大(EndDate)行如果NULL行不存在。例如,在这种情况下,供应商昨天被终止,但上周做了工作,我们将在下周支付。
我接受这个答案,因为它非常漂亮,它比najmeddine的NOT EXISTS回答稍微快一些(但由于索引选择良好,所以答案略有些微)。谢谢,基普。 :-) –
刚刚合并到我的代码库并根据实际数据进行测试。工程100%,没有显着的性能损失。再次感谢,基普!其他ADS用户的注意事项:COALESCE()调用需要添加一项:将它们都更改为COALESCE(EndDate,CAST('2037-01-01'AS SQL_DATE)),因为ADS不会自动从日期进行转换文字像其他数据库一样。 –
@Ken White:如果你有多于一行的NULL结束日期,你会得到多于一行的结果。我想这将被视为您的架构中的损坏数据。 – Kip