3

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

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

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

有什么建议么?

编辑:我要查找的是带有 NULL EndDate 的行(如果存在),或者带有 Max(EndDate) 的行(如果 NULL 行不存在)。例如,这包括供应商昨天被终止,但上周确实工作的情况,我们将在下周向他们付款。

4

5 回答 5

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运算符返回第一个非空参数,所以这基本上只是将空值设置为未来的某个时间,这样 SELECT MAX 将为您提供结束日期为 NULL 的参数(如果有)。

于 2009-09-24T15:55:17.050 回答
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)
        )
    )
于 2009-09-24T15:53:13.587 回答
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。

于 2009-09-24T15:51:16.653 回答
0

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

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

奥托姆代码

SELECT TransactionId, TransactionType
FROM TransactionList Tx
    INNER JOIN TransactionType TxType
        ON Tx.TransactionTypeId = TxType.TxTypeId
        AND Tx.TransactionDate Between TxType.StartDate and TxType.EndDate
于 2009-09-24T15:53:08.567 回答
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
于 2009-09-24T16:03:00.153 回答