如何根据生效日期获取当前记录?

时间:2014-02-07 02:13:57

标签: sql sql-server-2008

如何根据生效日期获取当前记录?我应该使用子查询吗?除了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 

我的目标是让当前的所有ResourceID都属于用户放入的OrganizationUnit。例如,如果用户将 SMESM1HTOVEOVE 放入OrganizationID参数然后它取出当前在 SMESM1HTOVEOVE 下的所有ReourceID。到目前为止,我的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

有人可以帮忙提供他们的意见吗?因为我将在下面使用它来存储我的存储过程。我也会把你的程序包括在内,供你自己阅读。

谢谢!

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

3 个答案:

答案 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)

答案 1 :(得分: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'

答案 2 :(得分: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