以数据库为例子,
有字段ID   [INT],
Text [NVARCHAR](1000)
Type [INT]搜索时,按照Text LIKE 匹配
搜索结果排序,必须按照Type交叉(假设Type值只有1,2,3,不允许出现连续的Type,除非没有其他值的记录)
求高效解法,谢谢不一定要用SQL,给出解法就行

解决方案 »

  1.   

    没看明白,排序规则?
    只有不允许出现连续的Type?
      

  2.   

    好像没说清楚,就是使排序结果按Type值交叉
      

  3.   

    id   type
    1    1
    2    1
    3    1
    4    2
    5    2
    6    3以上记录,假设全部匹配
    排序结果是
    1, 4, 6, 2, 5, 3
      

  4.   

    仅按Type值交叉,结果可不唯一,没有其他规则,比如相同的Type下其他字段排序
      

  5.   

    id  type 
    1    1 
    2    1 
    3    1 
    4    2 
    5    2 
    6    3 
    排序结果?1 1
    4 2
    6 3
    2 1
    5 2
    3 1
    ?
      

  6.   

    其他规则没有了,只要按Type分开就可以了
      

  7.   

    这个好像一个查询做不到,只能写个存储过程,用Cursor(游标)去做了。
      

  8.   

    /*
    功能 : 测试数据排序
    作者 : ascor
    时间 : 10-02-05
    */
    --填充数据
    declare @tb table (id int,  type int) 
    insert into @tb select 1  ,  1 
    union all select 2  ,  1 
    union all select  3  ,  1 
    union all select  4  ,  2 
    union all select  5  ,  2 
    union all select  6 ,   3 select b.id,b.type,
    (select count(1)+1 from @tb a where a.type=b.type and a.id<b.id ) as order2 
    from @tb  b 
    order by order2,type
    /*********测试结果*****/
    (所影响的行数为 6 行)id          type        order2      
    ----------- ----------- ----------- 
    1           1           1
    4           2           1
    6           3           1
    2           1           2
    5           2           2
    3           1           3(所影响的行数为 6 行)
      

  9.   


    /*
    功能 : 测试数据排序
    作者 : ascor
    时间 : 10-02-05
    */
    --填充数据
    declare @tb table (id int,  type int) 
    insert into @tb select 1  ,  1 
    union all select 2  ,  1 
    union all select  3  ,  1 
    union all select  4  ,  2 
    union all select  5  ,  2 
    union all select  6 ,   3 select b.id,b.type
    from @tb  b 
    order by (select count(1)+1 from @tb a where a.type=b.type and a.id<b.id ) ,type
    /*********测试结果******/
    (所影响的行数为 6 行)id          type        
    ----------- ----------- 
    1           1
    4           2
    6           3
    2           1
    5           2
    3           1(所影响的行数为 6 行)
      

  10.   


    哇,想法是不错,但是不行的:如你在插入一条数据试试,如:
    /*
    功能 : 测试数据排序
    作者 : ascor
    时间 : 10-02-05
    */
    --填充数据
    declare @tb table (id int,  type int) 
    insert into @tb select 1  ,  1 
            union all select 2  ,  1 
            union all select  3  ,  1 
            union all select  4  ,  2 
            union all select  5  ,  2 
            union all select  6 ,   3 
    union all select  6 ,   3 
    select b.id,b.type
    from @tb  b 
    order by (select count(1)+1 from @tb a where a.type=b.type and a.id<b.id ) ,type
    /*********测试结果******/
      

  11.   


    --SQL2005可以用row_number()declare @tb table (id int,  type int) 
    insert into @tb   select  1  ,  1 
            union all select  2  ,  1 
            union all select  3  ,  1 
            union all select  4  ,  2 
            union all select  5  ,  2 
            union all select  6 ,   3 select id,type
    from @tb
    order by row_number() over (partition by type order by id) ,id
      

  12.   

    我使用的办法是附加一列,进行排序统计,不管是用循环,或游标循环, 还是我这种,其实本质上都是一样的
     我敢说比游标快.sql的 select 机制 其实是一条一条记录读取的.  可以看成是依次获取数据, 我实在每获取一条记录 给赋值一个 排序字段,
    如果你要直接判断记录的先后顺序,再填充数据, 这个我无法估计. 
     ps,   这种情况, 你自己测试一下效果,  你再写一个使用游标进行计算的 比较下就知道了, 我没真是数据,无法计算
      

  13.   

    create table #tt (id int ,bm int)
    insert into  #tt
    select 1,1
    union all
    select 2,1
    union all
    select 3,1
    union all
    select 4,2
    union all
    select 5,2
    union all
    select 6,3
    union all
    select 7,4drop table #tt
    declare  @re table(deid int  identity(1,1),id int ,bm int)
    declare @i int 
    set @i=1while @i<(select   COUNT(*) from #tt) 
    begin 
      declare @j int 
      set @j=1
      while @j<=(select   MAX(bm) from #tt) 
        begin 
          insert into @re 
          select MIN(id),bm from #tt where bm=@j and id not in (select id from @re)
            group by bm
           print @i  print @j
           set @j=@j+1
         end
          set @i=@i+1
    end 
    select * from @re order by deid
      

  14.   

    我没有说游标比较快我也认为游标要慎用
    我是觉得,每次都进行一次count计算,会比较慢,本贴目的就为找个更快的
      

  15.   


    --如果是sql 2000,建议使用临时表,不要用游标
    declare @tb table (id int,  type int) 
    insert into @tb select 1  ,  1 
            union all select  2  ,  1 
            union all select  3  ,  1 
            union all select  4  ,  2 
            union all select  5  ,  2 
            union all select  6 ,  3 
    select id,type,tmp=0
    into #T
    from @tb order by type,iddeclare @tmp int, @type int, @i int
    set @i=1
    update #T
    set    @i=case when type=@type
    then @i+1
    else 1 end,
           @tmp=@i,
           @type=type,
           tmp=@tmpselect id,type  from #T  order by tmp, iddrop table #T
      

  16.   

      那个插啥数据, 人家那个id明显是字段的唯一标识,,,,   因为id字段不用做排序,   这个并不影响数据, 即使id不是唯一的标识字段,我相信他的表里面也可以找到一个唯一的标识字段. 用标识字段(甚至可以不是数值型的字段,只要是标识字段就行.)就可以了.
     至于在效率上, 因为没有真实数据, 无法做测试, 我只能估计, 我认为这是比较好的方法. 
      

  17.   

    #18的代码其实跟我的是一致的.  不过他的是sql2005,使用了新的方法.,  20#的代码明显累赘了, 
    #24  你可以用这个跟我的代码做下时间比较就行,  可能搞个50w数据就差不多看得出效果了. 其实原理都是一样的, 新增一个字段作为排序字段,.. 至于怎么填充那个排序字段, 我想不管你用什么办法,没更新一下那个排序字段都需要统计一下表记录..
      

  18.   

    可以用其他的辅助方法。。目前还没想到。。主要是用到Text的LIKE匹配,没办法提前计算出来
      

  19.   

    要是问我的大脑, 没了.... ..
    ps: 你好抠门 >_<
      

  20.   

    create table #tt (id int ,bm int) 
    insert into  #tt 
    select 1,1 
    union all 
    select 2,1 
    union all 
    select 3,1 
    union all 
    select 4,2 
    union all 
    select 5,2 
    union all 
    select 6,3 
    union all 
    select 7,4 drop table #tt 
    declare  @re table(deid int  identity(1,1),id int ,bm int) 
    declare @i int 
    set @i=1 while @i <(select  COUNT(*) from #tt) 
    begin 
      declare @j int 
      set @j=1 
      while @j <=(select  MAX(bm) from #tt) 
        begin 
          insert into @re 
          select MIN(id),bm from #tt where bm=@j and id not in (select id from @re) 
            group by bm 
          print @i  print @j 
          set @j=@j+1 
        end 
          set @i=@i+1 
    end 
    select * from @re order by deid 
    把这里面的  (select  MAX(bm) from #tt)  和(select  COUNT(*) from #tt)  赋给两个变量,就可以只计算一次了,只是会循环次数表多。不知道效率怎样
      

  21.   

    sql中,一般避免 cursor ,尽量不用子查询(在用exists时无所谓)。
    尤其大资料量。
      

  22.   


    我是指LS有人用子查询的时候,
    需在type和id上建索引,
    否则大数据量会慢
      

  23.   

    都有问题,试试这个数据
    id  type
    1    1
    2    1
    3    1
    4    1
    5    2
    6    2
    7    3都交错的话应该是
    1    1
    5    2
    2    1
    6    2
    3    1
    7    3
    4    1至少我现在还没有想到比较简单的方法,
    我现在的设想是,按type分组,共三组
    1(1,2,3,4)
    2(5,6)
    3(7)
    先取数量最多的那个个组,这里是type=1的一组,有四条记录
    然后交错插入新表,交错时,type=1这一组先开始,也以这一组结束,交错数据取剩下分组数量最多的那一组数据
    交错数据完成一轮后,如果剩下的分组还有数据,再继续下一轮
    实例中第一轮可以得出答案 1,5,2,6,3,7,4
     
      

  24.   


    看来还是我的说明有问题,我想我的意思应该是
    每次,在每个Type中只选出一条记录,以此类推。
      

  25.   

    至于按Type分组,到底哪个组会最多,要看Text字段的筛选了。。
    我发的那个排序示例,只为了说明我想如何排序