下边给出的数据,想实现 按PROID分组后再按ID倒排序,取每组第一条记录和第二条记录的值。
是想得到第一条记录中的FLOWID减第二条记录中的FLOWID的值是否大于1,
求SQL语句的写法。能实现取出按PROID分组,FLOWID没有按照ID的顺序的数据这个功能的语句。
ID PROID FLOWID
1 1 1
2 1 2
3 2 1
4 3 1
5 1 4
6 3 3
7 2 2
8 1 3
9 2 3
10 3 4
11 1 2
12 3 2

解决方案 »

  1.   

    select t.* from tb t where id in (select top 2 id from tb where PROID = t.PROID order by id desc)
      

  2.   


    select t.* from tb t where id in (select top 2 id from tb where PROID = t.PROID order by id )是前面两条的话
      

  3.   

    PROID分组后再按ID倒排序,取每组第一条记录和第二条记录的值 select * from
    (
    select * ,flag=row_number() over(partition by proid   ORDER BY id desc) from tb
    ) t 
    where flag<3
      

  4.   

    create table tb(ID int,PROID int,FLOWID int)
    insert into tb values(1 , 1 ,1) 
    insert into tb values(2 , 1 ,2) 
    insert into tb values(3 , 2 ,1) 
    insert into tb values(4 , 3 ,1) 
    insert into tb values(5 , 1 ,4) 
    insert into tb values(6 , 3 ,3) 
    insert into tb values(7 , 2 ,2) 
    insert into tb values(8 , 1 ,3) 
    insert into tb values(9 , 2 ,3) 
    insert into tb values(10, 3 ,4) 
    insert into tb values(11, 1 ,2) 
    insert into tb values(12, 3 ,2)
    goselect t.* from tb t where id in (select top 2 id from tb where PROID = t.PROID order by id desc) order by t.PROID  , t.id descdrop table tb/*
    ID          PROID       FLOWID      
    ----------- ----------- ----------- 
    11          1           2
    8           1           3
    9           2           3
    7           2           2
    12          3           2
    10          3           4(所影响的行数为 6 行)
    */
      

  5.   

    http://blog.csdn.net/fredrickhu/archive/2009/09/20/4574240.aspx
      

  6.   

    ----------------------------------------------------------------
    -- Author  :fredrickhu(我是小F,向高手学习)
    -- Date    :2009-10-13 17:06:39
    -- Version:
    --      Microsoft SQL Server 2005 - 9.00.4035.00 (Intel X86) 
    -- Nov 24 2008 13:01:59 
    -- Copyright (c) 1988-2005 Microsoft Corporation
    -- Developer Edition on Windows NT 5.2 (Build 3790: Service Pack 1)
    --
    ----------------------------------------------------------------
    --> 测试数据:[tb]
    if object_id('[tb]') is not null drop table [tb]
    go 
    create table [tb]([ID] int,[PROID] int,[FLOWID] int)
    insert [tb]
    select 1,1,1 union all
    select 2,1,2 union all
    select 3,2,1 union all
    select 4,3,1 union all
    select 5,1,4 union all
    select 6,3,3 union all
    select 7,2,2 union all
    select 8,1,3 union all
    select 9,2,3 union all
    select 10,3,4 union all
    select 11,1,2 union all
    select 12,3,2
    --------------开始查询--------------------------
    SELECT * FROM TB AS T WHERE (SELECT COUNT(1) FROM tb WHERE PROID = t.PROID  AND ID>T.ID)<2
    ----------------结果----------------------------
    /* ID          PROID       FLOWID
    ----------- ----------- -----------
    7           2           2
    8           1           3
    9           2           3
    10          3           4
    11          1           2
    12          3           2(6 行受影响)
    */
      

  7.   

    这样能取出前两行的数据,可怎么判断第二行的FLOWID 减 第一行的FLOWID>1呢?我需要这个差值,>1则数据异常,=1则数据正常
      

  8.   

    用3楼的方法略加修改得出结果,你们看看我改后对不对,能否实现结果.select * from
    (
        select * ,flag=row_number() over(partition by proid   ORDER BY id ) from #abc
    ) t 
    where flag<>flowid
      

  9.   

    create table tb(ID int,PROID int,FLOWID int)
    insert into tb values(1 , 1 ,1) 
    insert into tb values(2 , 1 ,2) 
    insert into tb values(3 , 2 ,1) 
    insert into tb values(4 , 3 ,1) 
    insert into tb values(5 , 1 ,4) 
    insert into tb values(6 , 3 ,3) 
    insert into tb values(7 , 2 ,2) 
    insert into tb values(8 , 1 ,3) 
    insert into tb values(9 , 2 ,3) 
    insert into tb values(10, 3 ,4) 
    insert into tb values(11, 1 ,2) 
    insert into tb values(12, 3 ,2)
    goselect m.* , case when m.FLOWID - n.FLOWID > 1 then '数据异常' when m.FLOWID - n.FLOWID = 1 then '数据正常' else '' end from
    (select t.* , px = (select count(1) from tb where PROID = t.PROID and id > t.id) + 1 from tb t) m,
    (select t.* , px = (select count(1) from tb where PROID = t.PROID and id > t.id) + 1 from tb t) n
    where m.PROID = n.PROID and m.px = 1 and n.px = 2
    drop table tb/*
    ID          PROID       FLOWID      px                   
    ----------- ----------- ----------- ----------- -------- 
    9           2           3           1           数据正常
    11          1           2           1           
    12          3           2           1           (所影响的行数为 3 行)
    */
      

  10.   

    又发现一个新的问题,如果PROID下只对应一个FLOWID就不行了,这样只有一行数据,没有第二行数据了。
    也就没法判断了。
    这样FLOWID直接跳过1是个2的话,也属于异常范围,应该怎么判断呢?
      

  11.   

    情况肯定会很多的,但是我们无法一一为你解答,希望你看懂我们的方法,自己测试.就你这个,可以考虑是left join的方法来做.例如:create table tb(ID int,PROID int,FLOWID int)
    insert into tb values(1 , 1 ,1) 
    insert into tb values(2 , 1 ,2) 
    insert into tb values(3 , 2 ,1) 
    insert into tb values(4 , 3 ,1) 
    insert into tb values(5 , 1 ,4) 
    insert into tb values(6 , 3 ,3) 
    insert into tb values(7 , 2 ,2) 
    insert into tb values(8 , 1 ,3) 
    insert into tb values(9 , 2 ,3) 
    insert into tb values(10, 3 ,4) 
    insert into tb values(11, 1 ,2) 
    insert into tb values(12, 3 ,2)
    insert into tb values(13, 4 ,1) -- 增加一条PROID=4的记录.
    goselect m.* , case when m.FLOWID - isnull(n.FLOWID,0) > 1 then '数据异常' when m.FLOWID - isnull(n.FLOWID,0) = 1 then '数据正常' else '' end from
    (select t.* , px = (select count(1) from tb where PROID = t.PROID and id > t.id) + 1 from tb t) m left join
    (select t.* , px = (select count(1) from tb where PROID = t.PROID and id > t.id) + 1 from tb t) n
    on m.PROID = n.PROID and n.px = 2 where m.px = 1 
    order by m.PROIDdrop table tb/*
    ID          PROID       FLOWID      px                   
    ----------- ----------- ----------- ----------- -------- 
    11          1           2           1           
    9           2           3           1           数据正常
    12          3           2           1           
    13          4           1           1           数据正常(所影响的行数为 4 行)
    */