2011-08-15 63 views
3

我有一個第三方表正在填充一些混亂的數據,我需要從中獲取最新的不同記錄。每年或每次「人員」變化時,表格都會被添加一行。該表基於最新的ActiveDate是正確的人。我創建了一個模擬表格和數據來顯示這一點。在不使用臨時表的情況下選擇不同記錄

CREATE TABLE `Persons` (
    `PersonId` varchar(200) NOT NULL, 
    `Name` varchar(200) NOT NULL DEFAULT '', 
    `ActiveDate` varchar(25) NOT NULL, 
    `ExpireDate` varchar(25) DEFAULT NULL, 
    `Job` varchar(200) NOT NULL DEFAULT '', 
    `Position` varchar(200) NOT NULL DEFAULT '' 
) 

和一些模擬數據:

Id  |`Name`  |ActiveDate    |ExpireDate    |Job  |`Position` 
--------------------------------------------------------------------------------------------------- 
J1234 |Doe, John  |2010-08-15 00:00:00  |2011-08-15 00:00:00 |Worker |Janitor 
J1234 |Doe, John  |2011-08-15 00:00:00  |0000-00-00 00:00:00 |Worker |Janitor 
777  |Doe, Jane  |2010-06-04 00:00:00  |0000-00-00 00:00:00 |Boss  |Janitor 
777  |Doe, Jane  |2011-04-30 00:00:00  |0000-00-00 00:00:00 |Boss  |Janitor 
654G  |Smith, Jane |2011-01-20 00:00:00  |0000-00-00 00:00:00 |Worker |Janitor 

該表還具有與實際上由最終用戶設置和EXPIREDATE列並非總是設置令我沮喪。目前,我正在使用一個虛擬表格將不同的記錄提取並存儲到當天。我會使用臨時表,但我不是100%確定如何在MySQL中,加上我不喜歡它們。我這樣做的方式只是暫時的希望有更好的SQL。

該數據然後必須加入大量的其他表來獲得成品。但是我仍然需要處理最初的一組不同的數據。從一開始就加入另一張桌子就不會工作。

因此,這裏是我怎麼拉我的數據,存儲,然後再拉後來,它joing其他表:

INSERT INTO tmp_Person (Id, `Name`, Job, `Position`) 
    SELECT DISTINCT Id, `Name`, Job, `Position` 
    FROM Person 

SELECT tmp_Person.Id, 
    tmp_Person.`Name`, 
    tmp_Person.Job, 
    tmp_Person.`Position`, 
    Pricing.Cost, 
    Pricing.Benefit 

    FROM tmp_Person 
    LEFT OUTER JOIN Pricing AS CL ON CL.PersonId = tmp_Person.Id 
     AND CL.PriceScredule = 'Major-Client' 
     AND CL.ExpireDate = '0000-00-00 00:00:00' 
    LEFT OUTER JOIN Pricing AS Inter ON Inter.PersonId = tmp_Person.Id 
     AND Inter.PriceScredule = 'Internal-Client' 
     AND Inter.ExpireDate = '0000-00-00 00:00:00' 

我怎麼可以這樣寫,以避免加工出來的成本使用臨時表的重複行(以任何形式)?我非常清楚地說明了這一點,如果不是,我可以很高興地補充或澄清。

+0

是否有可能有兩行具有相同的「Id」,但在「Name」或「Job」或「Position」中有所不同?否則,查詢可能會更優化。 –

+0

不,該ID實際上是我的數據中的一個獨特列。它也適用於其他數據庫,只是不在此數據中。我正在從第三方計費系統挖掘數據,他們只是每天向我們發送這個永無止境的數據流。然後,我通過撈出我們需要的東西。我試圖維護一個充滿古怪的遺留系統,來自第三方的數據充滿了更多的古怪。所有與我的代碼,希望...不是一個怪異的。 –

+0

也許你不應該兩次加入'Pricing'表,因爲你可以使用'Pricing'別名(假設它不會被改變)。實際上,您不能在SELECT子句中引用「Pricing」,它應該是「CL」或「Inter」。 –

回答

3

替換tmp_Person你所擁有的臨時表的代碼:

SELECT tmp_Person.Id, 
    tmp_Person.`Name`, 
    tmp_Person.Job, 
    tmp_Person.`Position`, 
    CL.Cost  AS MajorCost,    
    CL.Benefit AS MajorBenefit, 
    Inter.Cost AS InternalCost, 
    Inter.Benefit AS InternalBenefit 

    FROM 
     (SELECT DISTINCT Id, `Name`, Job, `Position` 
     FROM Person 
    ) 
     AS tmp_Person 
    LEFT OUTER JOIN Pricing AS CL ON CL.PersonId = tmp_Person.Id 
     AND CL.PriceScredule = 'Major-Client' 
     AND CL.ExpireDate = '0000-00-00 00:00:00' 
    LEFT OUTER JOIN Pricing AS Inter ON Inter.PersonId = tmp_Person.Id 
     AND Inter.PriceScredule = 'Internal-Client' 
     AND Inter.ExpireDate = '0000-00-00 00:00:00' 

由於@Andriy發現,在SELECT列表中使用Pricing.CostPricing.Benefit會提高錯誤。我想你在發佈時忘了改變它。

+0

我會在早上第一次嘗試。這肯定會節省更多的時間。更因爲數據庫老化(希望優雅)。 –

+2

您正在通過引用'Pricing'而不是'CL'或'Inter'(在SELECT子句中)複製OP的錯誤。 –

+0

@Andriy:Thnx,沒有注意到。 –

-1

在我意識到這個問題是針對mysql的,但主體應該是相同的,這將爲您獲取每個PersonID與Person表中最新的ActiveDate的記錄。

select * 
from 
(
select persons.*, ROW_NUMBER() over(partition by personid order by personid, activedate desc) as rn 
from persons 
) basedata 
where basedata.rn=1 
+0

不幸的是,MySQL沒有'ROW_NUMBER()'而沒有'OVER()'。根本沒有分析功能。 –

相關問題