2014-02-07 110 views
1

如何根據生效日期獲取當前記錄?我應該使用子查詢嗎? MAX有什麼我可以使用的嗎?如何根據生效日期獲取當前記錄?

我有這些表格的例子。

ResourceID is the ID number of the Resource. 
OrganizationId is the current Organization or Department of the Resource. 
Effective Date is the start date or the first day of the Resource in an Organization. 


ResourceID OrganizationID EffectiveDate 
VC1976  INTIN1HTHWYAMM 2009-12-23 00:00:00.000 
VC1976  INTIN1LGAMMAMS 2011-07-01 00:00:00.000 
VC1976  SMESM1HTOVEOVE 2012-07-01 00:00:00.000  
VC1976  APCAP1HTOVEOVE 2012-07-09 10:17:56.000 

ResourceID OrganizationID EffectiveDate 
JV2579  VNMVN1HTHWYCMM 2009-07-01 00:00:00.000 
JV2579  INTIN1HTHWYCMM 2011-07-02 00:00:00.000 
JV2579  SMESM1HTOVEOVE 2012-07-01 00:00:00.000 

ResourceID OrganizationID EffectiveDate 
RJ1939  INTIN1HTOVEOVE 1995-01-30 00:00:00.000 
RJ1939  INTIN1HTOVEOVE 2007-07-25 00:00:00.000 
RJ1939  SMESM1HTOVEOVE 2012-07-01 00:00:00.000 

ResourceID OrganizationID EffectiveDate 
PJ8828  AREAR1HTHWYRHD 2012-04-01 00:00:00.000 
PJ8828  SMESM1HTOVEOVE 2012-07-01 00:00:00.000 

ResourceID OrganizationID EffectiveDate 
RS1220  INTIN1HTHWYCMM 1981-01-06 00:00:00.000 
RS1220  SMESM1HTOVEOVE 2012-07-01 00:00:00.000 

我的目標是讓所有誰目前屬於該用戶將在OrganizationUnit工時單的資源的。例如,如果用戶將SMESM1HTOVEOVE在OrganizationID參數則使出渾身ReourceID那是目前在SMESM1HTOVEOVE。到目前爲止我的MAX查詢不起作用。

select OrganizationID, ResourceID, MAX(EffectiveDate) as EffectiveDate from ResourceOrganization 
where OrganizationID = 'SMESM1HTOVEOVE' 
group by OrganizationID, ResourceID, EffectiveDate 

以下是我上面簡短的MAX查詢的結果。這是錯誤的,因爲ResourceID VC1976目前屬於APCAP1HTOVEOVE,2012-07-09 10:17:56.000生效。

OrganizationID ResourceID EffectiveDate 

SMESM1HTOVEOVE JV2579  2012-07-01 00:00:00.000 
SMESM1HTOVEOVE PJ8828  2012-07-01 00:00:00.000 
SMESM1HTOVEOVE RJ1939  2012-07-01 00:00:00.000 
SMESM1HTOVEOVE RS1220  2012-07-01 00:00:00.000 
SMESM1HTOVEOVE VC1976  2012-07-01 00:00:00.000 

有人可以幫忙提供他們的意見嗎?因爲我將在下面使用這個存儲過程。我還會包括我的proc,供你自己細讀。

謝謝!

create table #Resources 
(
ResourceID nvarchar(30), 
OrganizationID nvarchar(15), 
EffectiveDate datetime, 
TimeEntryDate datetime 
) 

if @ResourceID <> '' 
begin 
insert into #Resources (ResourceID,OrganizationID,EffectiveDate) 

    select ro.ResourceID, ro.OrganizationID, ro.EffectiveDate from ResourceOrganization ro, 
    (select ResourceID, MAX(EffectiveDate) as maxEffectivedate from dbo.ResourceOrganization 
    where ResourceID = @ResourceID 
    group by ResourceID) as maxresults 
    where ro.ResourceID = maxresults.ResourceID 
    and ro.EffectiveDate = maxresults.maxEffectivedate 
    end 

else if @OrgUnit <> '' 
begin 
insert into #Resources (ResourceID,OrganizationID,EffectiveDate) 
    select ro.ResourceID, ro.OrganizationID, ro.EffectiveDate from ResourceOrganization ro, 
    (select ResourceID, MAX(EffectiveDate) as maxEffectivedate from dbo.ResourceOrganization 
    where OrganizationID like '' + @OrgUnit + '%' 
    group by ResourceID) as maxresults 
    where ro.ResourceID = maxresults.ResourceID 
    and ro.EffectiveDate = maxresults.maxEffectivedate 


else if @ResourceID <> '' and @OrgUnit <> '' 

begin 
insert into #Resources (ResourceID,OrganizationID,EffectiveDate) 

    select ro.ResourceID, ro.OrganizationID, ro.EffectiveDate 
    from ResourceOrganization ro, 
    (select ResourceID, MAX(EffectiveDate) as maxEffectivedate from dbo.ResourceOrganization 
    where ResourceID = @ResourceID 
    group by ResourceID) as maxresults 
    where ro.ResourceID = maxresults.ResourceID 
    and ro.EffectiveDate = maxresults.maxEffectivedate 
    end 
+0

您的表格中是否有任何唯一鍵?這將使它更容易。 – Jade

+0

嗨玉。不,它沒有任何獨特的表格。 –

回答

0

我想還有其他方法可以做到這一點,但我想這樣的作品:

DECLARE 
    @OrganizationID varchar(40) 

SET @OrganizationID = 'SMESM1HTOVEOVE' 

SELECT 
    ro.ResourceID, 
    ro.OrganizationID, 
    max(ro.EffectiveDate) 
FROM 
    ResourceOrganization ro 
WHERE 
    ro.OrganizationID = @OrganizationID 
GROUP BY 
    ro.ResourceID, 
    ro.OrganizationID 
HAVING 
    max(ro.EffectiveDate) = (
    SELECT 
     max(EffectiveDate) 
    FROM 
     ResourceOrganization 
    WHERE 
     ResourceID = ro.ResourceID) 

這裏有一個SQLFiddle一起玩。

編輯:其實,這可能是過於複雜。試試這個:

DECLARE 
    @OrganizationID varchar(40) 

SET @OrganizationID = 'SMESM1HTOVEOVE' 

SELECT 
    ro.ResourceID, 
    ro.OrganizationID, 
    ro.EffectiveDate 
FROM 
    ResourceOrganization ro 
WHERE 
    ro.OrganizationID = @OrganizationID 
    AND ro.EffectiveDate = (
    SELECT 
     max(EffectiveDate) 
    FROM 
     ResourceOrganization 
    WHERE 
     ResourceID = ro.ResourceID) 
+0

你真棒。謝謝Zec! –

0

你也可以嘗試使用這個CTE

;WITH tmpWithUID As 
(
    SELECT Row_Number() OVER(ORDER BY ResourceID, EffectiveDate, OrganizationID) AS rowNumber, 
      ResourceID, OrganizationID, EffectiveDate 
    FROM dbo.ResourceOrganization  
    GROUP BY ResourceID, EffectiveDate, OrganizationID 
) 
SELECT ResourceID, OrganizationID, EffectiveDate 
FROM tmpWithUID 
WHERE tmpWithUID.rowNumber IN (
      SELECT max(rowNumber) rowNumber 
      FROM tmpWithUID 
      GROUP BY ResourceID 
     ) 
     AND OrganizationID = 'SMESM1HTOVEOVE' 
+0

這也是正確的!謝謝Jade –

+0

我也比較Zec樣本,當我看執行計劃時,我的腳本以10%的差異運行。但我不確定其他SQL Server環境。 – Jade

+0

好的玉讓我跑一些系列的測試。感謝您幫助我 –

0

你可以使用光標嘗試。這個例子只是輸出到屏幕上,但你可以將結果插入一個臨時表中,然後返回結果,如果你想通過SQLDataAdapter或類似的方法來執行它。

SET NOCOUNT ON; 

DECLARE tmpCursor CURSOR FOR 
SELECT DISTINCT ResourceID 
    FROM ResourceOrganization 
ORDER BY 1 

OPEN tmpCursor 

DECLARE @resID VARCHAR(12) 
DECLARE @orgID VARCHAR(12) 
DECLARE @effDate INT 

FETCH NEXT FROM tmpCursor INTO @resID 

PRINT '----------- -------------- ------------------' 
PRINT 'Resource ID OrganizationID Effective Date' 
PRINT '----------- -------------- ------------------' 
WHILE @@FETCH_STATUS = 0 BEGIN 
    SELECT @effDate = MAX(EffectiveDate) 
    FROM ResourceOrganization 
    WHERE ResourceID = @resID 

    SELECT TOP 1 @orgID = OrganizationID 
    FROM ResourceOrganization 
    WHERE ResourceID = @resID AND EffectiveDate = @effDate 

    PRINT @resID + ' ' + @orgID + ' ' + CONVERT(VARCHAR(24), @effDate, 109) 

    FETCH NEXT FROM tmpCursor INTO @resID 
END 
PRINT '----------- -------------- ------------------' 

CLOSE tmpCursor 
DEALLOCATE tmpCursor 
GO