仅匹配JOIN中存在多个特定行的特定行

时间:2009-09-24 15:44:01

标签: sql advantage-database-server

(Advantage Database Server)我有一个服务提供者表,出于审计目的,从不删除。他们有开始日期和结束日期;在名称或地址等更改的情况下,现有行将结束日期,创建新行,并为更改的数据分配新的开始日期。

在处理向这些提供商付款的过程中,我需要一个摘要页面,其中列出了提供商名称,地址,标识符(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(EndDate)。

我在其他情况下处理此问题(例如,使用

找到特定日期提供的服务的正确ProvID)
p.EndDate is null or (s.ServiceDate BETWEEN p.StartDate AND p.EndDate)

不幸的是,由于问题查询是带有聚合的GROUP BY,因此服务日期不可用。

有什么建议吗?

编辑:我正在寻找的是具有NULL EndDate的行(如果存在),或者如果NULL行不存在则具有Max(EndDate)的行。这包括案例,例如,供应商昨天被终止,但上周工作,我们将在下周付款。

5 个答案:

答案 0 :(得分:4)

所以我猜如果有一个NULL结束日期的行,你想要那个,否则你想要一个具有最大结束日期的行?

我不确定ADS,但以下内容适用于SQL Server:

SELECT ... FROM service s
INNER JOIN provider p ON p.ProvID = s.ProvID
AND (COALESCE(p.EndDate, '2037-01-01') = (
   SELECT Max(COALESCE(EndDate, '2037-01-01')) FROM
   provider lu WHERE lu.ProvID = s.ProvID)
)

COALESCE运算符返回第一个非null参数,所以这基本上只是将空值设置为将来的一个时间,因此SELECT MAX将为您提供具有NULL结束日期的那个是一个。

答案 1 :(得分:3)

在第二个条件中,只有在没有NULL EndDate

的情况下才能获得最大值
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)
         AND NOT EXISTS (SELECT NULL 
                           FROM provider lu 
                          WHERE lu.ProvID = s.ProvID 
                            AND lu.EndDate IS NULL)
        )
    )

答案 2 :(得分:0)

也许使用子查询代替第二个表:

SELECT ... FROM service s
INNER JOIN (SELECT ..., Max(EndDate) FROM
   provider lu WHERE lu.ProvID = s.ProvID GROUP BY ...) p ON p.ProvID = s.ProvID

如果没有最终结束日期,则假设您将返回NULL。

答案 3 :(得分:0)

您所指的是数据仓库的Type-2维度。

您必须通过StartDate和EndDate通过ID 加入才能获得正确的数据。

OTTOMH代码

SELECT TransactionId, TransactionType
FROM TransactionList Tx
    INNER JOIN TransactionType TxType
        ON Tx.TransactionTypeId = TxType.TxTypeId
        AND Tx.TransactionDate Between TxType.StartDate and TxType.EndDate

答案 4 :(得分:0)

提供商表中的内容表示当前日期? EndDate = NULL,EndDate = Max(EndDate)或EndDate ='9999-01-01'?这三个都是有效的选择,但这应该是明确的,因为如果不是你最终会在查询中最终出现重复的行,无论你如何巧妙地设计这个特定的查询。所以我建议在提供者表中修复它,然后这样的事情应该起作用:

select p.name, p.address, p.id, sum(s.amount)
  from provider p
  join service s on p.id=s.provider_id
where p.endDate is NULL
group by p.name, p.address, p.id