SQL

ID,编号,开始时间,结束时间,类型
1,1,2009-7-1,2009-10-1,ee 
2,1,2009-7-2,2009-10-20,tt 
3,2,2009-7-3,2009-9-5,uu 
4,2,2009-7-4,NULL,tt 
5,2,2009-7-5,NULL,ii 
6,3,2009-7-6,2009-10-7,ii 
7,3,2009-7-7,2009-10-8,oo 
8,3,2009-7-7,2009-10-8,rr 
9,4,2009-7-1,2009-10-9,ii
10,4,2009-7-1,2009-10-10,rr
11,4,NULL,NULL,uu
12,4,NULL,NULL,ee
13,5,2009-7-1.2009-10-8,KK
14,5,2009-10-8,NULL,II
15,5,NULL,NULL,JJ
15,5,NULL,NULL,VV
................. 
这样的SQL语句: 
1、当编号中结束时间有NULL字段的,要是NULL有多个时,从有NULL的数据中选择开始时间最小的,如上面的编号2,则选2009-7-4 
否则就选NULL的哪个 
2、当编号中结束时间没有NULL字段时,则选结束时间最大的,结束时间可能是有重复的,则选任意一个就可以如3,可以选    3,2009-7-7,2009-10-8,rr或3,2009-7-7,2009-10-8,oo 
3、当一个编号里存在结束时间和开始都是NULL的时候,任意选一个NULL行就行,比如编号4,可以选4,NULL,NULL,uu或           4,NULL,NULL,ee
4、向编号5那样的,结束时间有NULL,开始时间也有NULL,就从开始时间和结束时间都是NULL中任选一个就可以了,选5,NULL,NULL,VV 或 5,NULL,NULL,JJ如上面的例子的结果: 
ID,编号,开始时间,结束时间,类型
2,1,2009-7-2,2009-10-20,tt 
4,2,2009-7-4,NULL,tt 
8,3,2009-7-7,2009-10-8,rr 
11,4,NULL,NULL,uu
15,5,NULL,NULL,VV
.... 
这样的SQL语句怎么写啊? 数据比较多呢?怎么写

解决方案 »

  1.   

    开始的答案是:
    SELECT * FROM TB T WHERE 
        编号 in(SELECT 编号 FROM TB T WHERE 结束时间 IS NULL)  AND 结束时间 IS NULL
            AND NOT EXISTS(SELECT 1 FROM TB WHERE 编号=T.编号 AND 开始时间=T.开始时间 AND  类别>T.类别 ) 
        AND NOT EXISTS(SELECT 1 FROM TB WHERE 编号=T.编号 AND 开始时间<T.开始时间 AND  类别>T.类别 ) UNION ALLSELECT * FROM TB T WHERE 
        编号 in(SELECT 编号 FROM TB T WHERE 结束时间 IS NULL)  AND 结束时间 IS NULL 
        AND EXISTS( SELECT 1 FROM TB WHERE 编号=T.编号 AND 开始时间>T.开始时间)UNION ALLSELECT * FROM TB T WHERE 
        NOT EXISTS(SELECT 1 FROM TB WHERE  t.编号=编号  AND t.开始时间=开始时间 AND 类别>T.类别 )
        AND NOT EXISTS(SELECT 1 FROM TB WHERE t.编号=编号  AND 开始时间>T.开始时间)
        and 编号 not in 
                (SELECT 编号 FROM TB T WHERE 结束时间 IS NULL)order by t.编号
    但是这样太慢了...
    我改了一下变成这样..
    SELECT *   FROM TB T WHERE 
        编号 in(SELECT 编号 FROM TB T WHERE 结束时间 IS NULL)  AND 结束时间 IS NULL
            AND 开始时间=(SELECT min(开始时间) FROM TB WHERE 编号=T.编号 AND 结束时间 IS NULL ) 
        AND 序号=(SELECT max(序号) FROM TB WHERE 编号=T.编号 AND 结束时间 IS NULL ) 
    UNION ALL
    SELECT *   FROM TB T WHERE 
        编号 in(SELECT 编号 FROM TB T WHERE 结束时间 IS not NULL)  AND 结束时间 IS not NULL
            AND 结束时间=(SELECT max(结束时间) FROM TB WHERE 编号=T.编号 AND 结束时间 IS not NULL ) 
        AND 序号=(SELECT max(序号) FROM TB WHERE 编号=T.编号 AND 结束时间 IS not NULL ) 
    变成这样后但是得到的数据不全阿。。
      

  2.   

    select * from tb where 结束时间 IS NULL and (开始时间 in(select min(开始时间) from tb))
    union all
    select top 1 * from tb where 结束时间  is not null and (结束时间 in (select max(结束时间) from tb ))
    union all 
    select top 1 from tb where (开始时间 is null) and (结束时间 is null)
    union all
    select top 1 from tb where (开始时间 is null  or 结束时间 is null)
      

  3.   

    select * from tb where 结束时间 IS NULL and (开始时间 in(select min(开始时间) from tb)) 
    union all 
    select top 1 * from tb where 结束时间  is not null and (结束时间 in (select max(结束时间) from tb )) 
    union all 
    select top 1 * from tb where (开始时间 is null) and (结束时间 is null) 
    union all 
    select top 1 * from tb where (开始时间 is null  or 结束时间 is null) 
    不好意思,把×号搞没了。
      

  4.   


    select * into #s from tb T where 结束时间 IS NULL and (开始时间 in(select min(开始时间) from tb where 编号=T.编号)) 
    union all 
    select  * from tb T where 结束时间  is not null and (结束时间 in (select max(结束时间) from tb where 编号=T.编号 )) 
    union all 
    select  * from tb T where (开始时间 is null) and (结束时间 is null)  
    union all 
    select * from tb T where (开始时间 is null  or 结束时间 is null) 
    select identity(int) as 序号,编号,类型,开始时间,结束时间 into #r from #s
    select * from #r a inner join (select max(序号) as  序号,编号 from #r group by 番号 )b on a.序号=b.序号
    drop table #s,#r我该成这样了,得到了我要的结果了,还很快.
    但是我把条件4改了一下
    4、向编号5那样的,结束时间有NULL,开始时间也有NULL,选有开始时间的,结束时间是NULL,5,2009-10-8,NULL,II 
    改成这样怎么修改上面的语句啊?