2

我试图根据表格看起来像这样的状态代码来查找表格中的空白。

状态表:

StateID (PK) | Code
--------------------
1            | AK
2            | AL
3            | AR

状态模型表:

StateModelID | StateID | EfftiveDate            | ExpirationDate
-------------------------------------------------------------------------
1            |  1      | 2012-06-28 00:00:00.000| 2012-08-02 23:59:59.000
2            |  1      | 2012-08-03 00:00:00.000| 2050-12-31 23:59:59.000
3            |  1      | 2055-01-01 00:00:00.000| 2075-12-31 23:59:59.000

我正在使用的查询如下:

Declare @gapMessage varchar(250)
SET @gapMessage = ''

select
@gapMessage = @gapMessage + 
  (Select StateTable.Code FROM StateTable where t1.StateID = StateTable.StateID) 
  + ' Row ' +CAST(t1.StateModelID as varchar(6))+' has a gap with '+
  CAST(t2.StateModelID as varchar(6))+ CHAR(10)
   from StateModel t1
   inner join StateModel t2
    on
       t1.StateID = t2.StateID
       and DATEADD(ss, 1,t1.ExpirationDate) < t2.EffectiveDate
       and t1.EffectiveDate < t2.EffectiveDate

 if(@gapMessage != '')
 begin         
Print 'States with a gap problem'
PRINT @gapMessage
 end
 else
 begin
PRINT 'No States with a gap problem'
 end

但是通过上表示例,我得到以下输出:

States with a gap problem
AK Row 1 has a gap with 3
AK Row 2 has a gap with 3

无论如何要重组我的查询,以便不显示 1 和 3 之间的差距,因为 1 和 2 之间没有差距?我正在使用 MS sql server 2008 谢谢

4

3 回答 3

3
WITH
  sequenced AS
(
  SELECT
    ROW_NUMBER() OVER (PARTITION BY StateID ORDER BY EfftiveDate) AS SequenceID,
    *
  FROM
    StateModel
)
SELECT
  *
FROM
  sequenced    AS a
INNER JOIN
  sequenced    AS b
    ON  a.StateID    = b.StateID
    AND a.SequenceID = b.SequenceID - 1
WHERE
  a.ExpirationDate < DATEADD(second, -1, b.EfftiveDate)

为了使其尽可能有效,还要添加一个索引(StateID, EfftiveDate)

于 2012-08-06T16:30:45.340 回答
1

我只想把功劳归功于 MatBailie,但还没有积分,所以我想我会帮助任何其他寻找类似解决方案的人,这些解决方案可能希望像我需要的那样更进一步。我已将他的代码(涉及会员注册)的应用程序更改为与此处示例相同的语言。

就我而言,我需要这些东西:

  1. 我有两张相似的表格,我需要将它们发展成一张总表格。在本例中,让我们制作这样的表格:SomeStates + OtherStates = UpdatedTable。这些在 AS 子句中是 UNIONED。
  2. 由于间隙,我不想删除任何行,但我想在 StateID 级别上标记它们。这是作为附加列“StateID_GapFlag”添加的。
  3. 我还想添加一列来保存最旧的或 MIN(EffectiveDate)。这将在以后的 SUM(period) 计算中使用,以获得总持续时间,不包括间隙。这是“MIN_EffectiveDate”列。

    ;WITH sequenced     
    ( SequenceID
    ,EffectiveDate
    ,ExpirationDate)
    AS
        (select 
        ROW_NUMBER() OVER (PARTITION BY StateID ORDER by EffectiveDate) as SequenceID,
        * from  (select EffectiveDate, ExpirationDate from SomeStates
                    UNION ALL
                (select EffectiveDate, ExpirationDate from OtherStates)
                ) StateModel
        where 
            EffectiveDate > 'filter'
        )
    Select DISTINCT 
            IJ1.[MIN_EffectiveDate]
            ,coalesce(IJ2.GapFlag,'') as [MemberEnrollmentGapFlag]
            ,EffectiveDate
            ,ExpirationDate
    into UpdatedTable 
    from sequenced seq
            inner join 
                (select StateID, min(EffectiveDate) as 'MIN_EffectiveDate'
                    from sequenced 
                    group by StateID
                ) IJ1
            on seq.member# = IJ1.member
            left join
                (select a.member#, 'GAP' as 'StateID_GapFlag'
                    from sequenced a
                    inner join 
                        sequenced b
                            on a.StateID = b.StateID
                            and a.SequenceID = (b.sequenceID - 1)
                        where a.ExpirationDate < DATEADD(day, -1, b.EffectiveDate)
                ) LJ2
            on seq.StateID = LJ2.StateID
    
于 2014-01-30T15:04:57.327 回答
0

您可以使用ROW_NUMBER为每个状态提供 stateModel 的排序,然后检查连续行的第二个差异是否不超过 1。类似于:

;WITH Models (StateModelID, StateID, Effective, Expiration, RowOrder) AS (
    SELECT StateModelID, StateID, EffectiveDate, ExpirationDate,
           ROW_NUMBER() OVER (PARTITION BY StateID, ORDER BY EffectiveDate)
    FROM StateModel
)
SELECT F.StateModelId, S.StateModelId
FROM Models F
CROSS APPLY (
    SELECT M.StateModelId
    FROM Models M
    WHERE M.RowOrder = F.RowOrder + 1
      AND M.StateId = F.StateId
      AND DATEDIFF(SECOND, F.Expiration, M.Effective) > 1
) S

这将为您提供有间隙的行的状态模型 ID,您可以按照自己的意愿对其进行格式化。

于 2012-08-06T16:30:55.787 回答