2014-02-07 134 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