1,B,2014-07-20
1,B,2014-07-10
因为针对8月份,当前有效类型是B(1,B,2014-07-20),但前条也是B类,故取1,B,2014-07-102,C,2014-07-20
因为针对8月份,当前有效类型是C(2,C,2014-07-20),但前条是B类,故取当前条2,C,2014-07-20明白,请指点. 谢谢

解决方案 »

  1.   

    不是太懂您的意思, 截至到7月的期待结果:
    1,B,2014-07-10   正生效
    1,A,2014-04-10   也在生效
    2,C,2014-07-20   正生效
    2,B,2014-07-10   正生效
    2,A,2014-02-10   也正生效
    截至到8月的期待结果:
    1,B,2014-07-10   正生效
    2,C,2014-07-20   正生效
    可以问您下,1 那么如何区分“正生效”和“也正生效” 
                            2 截至到8月的意思是只要上一个月(相对月8月)的数据吗
      

  2.   

    其实就是想得到截止某日期的最后有效1条数据,如果是同类的话,就向前追溯日期。
    源数据:
    1,B,2014-07-20
    1,B,2014-07-10
    1,A,2014-05-20
    1,A,2014-04-102,C,2014-07-20
    2,B,2014-07-10
    2,C,2014-04-10
    2,A,2014-02-10例如7月份,当前有效是
    1,B,2014-07-201,A,2014-05-202,C,2014-07-20
    2,B,2014-07-10
    2,C,2014-04-10
    因为针对7月份,当前有效类型是B(1,B,2014-07-20),但前条也是B类,故取1,B,2014-07-10;
    但当前有效类型是A(1,A,2014-05-20),理论上失效是(1,B,2014-07-10) , 所以7月份还有效,但前条也是A类(1,A,2014-04-10),故取当前条1,A,2014-04-10;
    ...对于2. 类似例如8月份,当前有效是
    1,B,2014-07-20
    2,C,2014-07-20
    因为针对8月份,当前有效类型是B(1,B,2014-07-20),但前条也是B类,故取1,B,2014-07-10;
    但当前有效类型是C(2,C,2014-07-20),但前条是B类,故取当前条2,C,2014-07-20
      

  3.   

    “其实就是想得到截止某日期的最后有效1条数据,如果是同类的话,就向前追溯日期。”
    这就话我理解是这样:如果对于相同的SID和Type,并且在一个月内有多条(>=2)记录,取日期最小的一条记录;
                                            如果对于相同的SIP和Type,并且在一个月内只有一条记录,则取这条记录。可以这样理解吗? 另外,对于7月份的记录为什么没有Record(2,A,2014-02-10)这条记录?
      

  4.   

    第一步 如果 type 连续相同取 日期最小的那条记录, 如果不连续相同 就取本条记录。
    结果1,B,2014-07-101,A,2014-04-102,C,2014-07-20
    2,B,2014-07-10
    2,C,2014-04-10
    2,A,2014-02-10
    然后 SID 相同  取日期最大的 也就是最近日期的
    最后结果
    1,B,2014-07-10
    2,C,2014-07-20
    希望大家能看懂~~~
      

  5.   

    还是没看懂。 感觉一直在变。 安装楼主8楼的说法。我是在看不出来。对于同一个结果集截止日期是7月 8月对结果有啥影响。 而且 你这个用了连续相同。那么是默认这个结果集是有序的。 那么应该有一个有一个准确的排序规则。从发出来的数据看 应该是order by id,date desc。
      

  6.   

    源数据:
    sid,type,edate(生效日期)
    1,B,2014-07-20 开始生效,前条失效
    1,B,2014-07-10 开始生效,前条失效
    1,A,2014-05-20 开始生效日,前条失效
    1,A,2014-04-10 开始生效2,C,2014-07-20 开始生效,前条失效
    2,B,2014-07-10 开始生效,前条失效
    2,C,2014-04-10 开始生效,前条失效
    2,A,2014-02-10 开始生效不好意思,表达能力有限, 简单实例说明下。
    比如7月份(2014-07-01~~2014-07-31)
    理论上按照sid,type,取出生效的数据。应该是
    1,B,2014-07-20 
    1,B,2014-07-10
    1,A,2014-05-20
     
    2,C,2014-07-20
    2,B,2014-07-10
    2,C,2014-04-10
    但是对应SID=1;2条B连续,所以取最小生效日期,即1,B,2014-07-10,
    故所需结果为
    1,B,2014-07-10
    1,A,2014-05-20;
    但对于SID-2,那3条都是间隔类型的,所以全部需要
    比如8月份(2014-08-01~~2014-08-31)
    按照sid,type,取出生效的数据。应该是
    1,B,2014-07-20 
    2,C,2014-07-20 
    但是对应SID=1;2条B连续,所以取最小生效日期,即1,B,2014-07-10,
    但对于SID=2,无连续,所以只取那条即可:2,C,2014-07-20 不知明白不? 
      

  7.   

    更加不明白。
    你所有举例的 edate 没有8月份的,怎么会查询7月份、8月份能有不同的结果?
      

  8.   


    那些记录都是SID对应的生效历史记录;对于8月份来说,不同SID对应的最后1条一直生效到现在,所以8月份需要数据如上述
      

  9.   


    SID:...1,A,2014-05-20  变为  1,B,2014-07-10,说明到2014-07-10之前它还有效;
    同理SID:...
    2,C,2014-04-10 变为 2,B,2014-07-10,说明到2014-07-10之前它还有效
      

  10.   


    SID:...1,A,2014-05-20  变为  1,B,2014-07-10,说明到2014-07-10之前它还有效;
    同理SID:...
    2,C,2014-04-10 变为 2,B,2014-07-10,说明到2014-07-10之前它还有效
    既然是“2014-07-10之前它还有效”
    为什么从 2014-07-31 和 2014-08-31 看就不一样了呢?
      

  11.   


    SID:...1,A,2014-05-20  变为  1,B,2014-07-10,说明到2014-07-10之前它还有效;
    同理SID:...
    2,C,2014-04-10 变为 2,B,2014-07-10,说明到2014-07-10之前它还有效
    既然是“2014-07-10之前它还有效”
    为什么从 2014-07-31 和 2014-08-31 看就不一样了呢?SID:...1,A,2014-05-20  变为  1,B,2014-07-10,说明到2014-07-10之前它还有效,到8月份已失效了,所以7月份的有效记录应该包括它
      

  12.   

    毫无逻辑!
    edata 到底是生效日还是失效日?如果是生效日,你16楼的说法完全矛盾。如果是失效日,查7月份时的预期结果怎么会有:
    1,A,2014-04-10
    2,C,2014-04-10
      

  13.   

    源数据:(对应sid,type的有效记录历史表,edate 相当于生效日期,也相对前条记录来说是失效日期)
    sid,type,edate(生效日期)
    1,B,2014-07-20
    1,B,2014-07-10
    1,A,2014-05-20
    1,A,2014-04-10 2,C,2014-07-20 
    2,B,2014-07-10 
    2,C,2014-04-10 
    2,A,2014-02-10 不好意思,表达能力有限, 简单实例说明下。
    比如7月份(2014-07-01~~2014-07-31)
    理论上按照sid,type,取出有效的数据。应该是
    1,B,2014-07-20 
    1,B,2014-07-10
    1,A,2014-05-20
     
    2,C,2014-07-20
    2,B,2014-07-10
    2,C,2014-04-10
    但是对应SID=1;2条B连续,所以取最小生效日期,即1,B,2014-07-10;对于1,A,2014-05-20这条,因为5.20生效,相对于7.10失效,所以7月份是有效数据
    故所需结果为
    1,B,2014-07-10
    1,A,2014-05-20;
    但对于SID-2,那3条都是间隔类型的,所以全部需要
    比如8月份(2014-08-01~~2014-08-31)
    按照sid,type,取出有效的数据。只有
    1,B,2014-07-20 
    2,C,2014-07-20 
    但是对应SID=1,B,2014-07-20 ,前条也是B类,所以取最小生效日期,即1,B,2014-07-10,
    但对于SID=2,C,2014-07-20 ,前条不是C类,所以只取那条即可:2,C,2014-07-20 不知明白不? 其实就是根据sid,type取当前还有效的记录,同类连续还有效的取最小的。
      

  14.   

    WITH test (sid,type,edate) AS (
        SELECT 1,'B','2014-07-20' UNION ALL
        SELECT 1,'B','2014-07-10' UNION ALL
        SELECT 1,'A','2014-05-20' UNION ALL
        SELECT 1,'A','2014-04-10' UNION ALL
        SELECT 2,'C','2014-07-20' UNION ALL
        SELECT 2,'B','2014-07-10' UNION ALL
        SELECT 2,'C','2014-04-10' UNION ALL
        SELECT 2,'A','2014-02-10'
    ),
    o (sid,type,edate,n) AS (
        SELECT *,
               ROW_NUMBER() OVER (PARTITION BY sid ORDER BY edate DESC)
          FROM test
    ),
    cte(sid,type,edate,n,expdate) AS (
        SELECT *, '9999-12-31'
          FROM O
         WHERE n=1
        UNION ALL
        SELECT o.*, cte.edate
          FROM cte
          JOIN o
            ON o.sid = cte.sid
           AND o.n = cte.n+1
    )
    SELECT *
      FROM cte
     WHERE expdate >= '2014-07-01'
       AND NOT EXISTS (SELECT *
                         FROM cte c2
                        WHERE c2.sid = cte.sid
                          AND c2.type = cte.type
                          AND c2.n = cte.n-1
                          AND c2.expdate >= '2014-07-01'
                      )
    ORDER BY sid,edate
    7月
            sid type edate                         n expdate
    ----------- ---- ---------- -------------------- ----------
              1 A    2014-05-20                    3 2014-07-10
              1 B    2014-07-20                    1 9999-12-31
              2 C    2014-04-10                    3 2014-07-10
              2 B    2014-07-10                    2 2014-07-20
              2 C    2014-07-20                    1 9999-12-31
    8月
            sid type edate                         n expdate
    ----------- ---- ---------- -------------------- ----------
              1 B    2014-07-20                    1 9999-12-31
              2 C    2014-07-20                    1 9999-12-31
      

  15.   

    谢谢!
    那么复杂,有没有简单点。sql 2005 不知道是否支持?但是有个问题,7月份的数据...
    1,'A','2014-05-20' 实际还是有效的,但前条也是同类,所以结果要取1,'A','2014-04-10'
      

  16.   


    没看懂。理论上按照sid,type,取出生效的数据。应该是
    1,B,2014-07-20 
    1,B,2014-07-10
    1,A,2014-05-20
     
    2,C,2014-07-20
    2,B,2014-07-10
    2,C,2014-04-10  为啥是这个 排除的2条为啥排除了?
      

  17.   

    终于看明白了。这就是个相对于SID对应时间一次生效记录。现在需要找出在7月(任何一天)有生效过的记录。但是对于相邻的记录比如第一行。第二行
     如果他们的TYPE 也相同 我们会取最先生效的记录。
    对这个表结构有点想法。对于
    1,B,2014-07-20 
    1,B,2014-07-10 对于这个 不插入第一行。也是第二行生效 为啥要插入。
      

  18.   

    1,'A','2014-04-10' 在 2014-05-20 就失效了!
    下面是cte内容,失效日expdate。
            sid type edate                         n expdate
    ----------- ---- ---------- -------------------- ----------
              1 A    2014-04-10                    4 2014-05-20
              1 A    2014-05-20                    3 2014-07-10
              1 B    2014-07-10                    2 2014-07-20
              1 B    2014-07-20                    1 9999-12-31
              2 A    2014-02-10                    4 2014-04-10
              2 C    2014-04-10                    3 2014-07-10
              2 B    2014-07-10                    2 2014-07-20
              2 C    2014-07-20                    1 9999-12-31
      

  19.   

    1,'A','2014-04-10' 在 2014-05-20 就失效了!

    1,'A','2014-04-10' 在 2014-05-20 就失效了!但是他们类型都是A,所以还得取它作为统计依据现在有项目需要检索人员当前有效职级的服务年限,所以给出类似实例;
    因为人员的变动历史不只有职级变化,还有工作地点等;如果有效期内连续职级相同的需要找最小的生效时间;所以如上例
    假如 1,'A','2014-04-10'   变化到1,'A','2014-05-20' 只是地点变化,而类型A 未变,而1,'A','2014-05-20' 变化到 1 B    2014-07-10 类型发生了变化,对于7月份1,A,2014-05-20 也是有效的;所以7月份统计A类型年限必须使用2014-04-10.。而不是2014-05-20。。(实际需要结果是2014-07-10 减 2014-04-10,...)
      

  20.   

    逻辑太混乱了!你先做个中间表,把
    1,A,2014-05-20
    1,A,2014-04-10
    处理成一条
    1,A,2014-04-10
    然后再统计。
      

  21.   

    如表A:(sid,type,edate)
    sid,type,edate
    1,B,2014-07-20
    1,B,2014-07-10
    1,A,2014-05-20
    1,A,2014-04-102,C,2014-07-20
    2,B,2014-07-10
    2,C,2014-04-10
    2,A,2014-02-10=====================================
    select a.* from 
    (
    SELECT a.etype, a.eid, a.edate  
    FROM z_table a 
    left outer join z_table b 
    on a.eid=b.eid and b.edate=(select max(edate) from z_table c 
    where c.eid=a.eid and c.edate<a.edate)
    where 1=1
    and a.etype<>isnull(b.etype, 'AAA')
    ) a 
    where not exists (select 1 from v_z_table b 
    where b.eid=a.eid and b.edate>a.edate and b.edate<='2014-07-01')
    and a.edate<'2014-08-01'
    order by a.eid, a.edate