(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