1.取款ss0001的同一type(只有ABC三种)的最大rev的物料的con. 
select t.* from tb t where rev = (select max(rev) from tb where type = t.type)

解决方案 »

  1.   

    2. 如果mat唯一, 根据mat取用量, 如果不唯一, 根据mat和component取各type的cons. 读不懂.如果是行列转换,参考如下:
    /*
    标题:普通行列转换(version 2.0)
    作者:爱新觉罗.毓华 
    时间:2008-03-09
    地点:广东深圳
    说明:普通行列转换(version 1.0)仅针对sql server 2000提供静态和动态写法,version 2.0增加sql server 2005的有关写法。问题:假设有张学生成绩表(tb)如下:
    姓名 课程 分数
    张三 语文 74
    张三 数学 83
    张三 物理 93
    李四 语文 74
    李四 数学 84
    李四 物理 94
    想变成(得到如下结果): 
    姓名 语文 数学 物理 
    ---- ---- ---- ----
    李四 74   84   94
    张三 74   83   93
    -------------------
    */create table tb(姓名 varchar(10) , 课程 varchar(10) , 分数 int)
    insert into tb values('张三' , '语文' , 74)
    insert into tb values('张三' , '数学' , 83)
    insert into tb values('张三' , '物理' , 93)
    insert into tb values('李四' , '语文' , 74)
    insert into tb values('李四' , '数学' , 84)
    insert into tb values('李四' , '物理' , 94)
    go--SQL SERVER 2000 静态SQL,指课程只有语文、数学、物理这三门课程。(以下同)
    select 姓名 as 姓名 ,
      max(case 课程 when '语文' then 分数 else 0 end) 语文,
      max(case 课程 when '数学' then 分数 else 0 end) 数学,
      max(case 课程 when '物理' then 分数 else 0 end) 物理
    from tb
    group by 姓名--SQL SERVER 2000 动态SQL,指课程不止语文、数学、物理这三门课程。(以下同)
    declare @sql varchar(8000)
    set @sql = 'select 姓名 '
    select @sql = @sql + ' , max(case 课程 when ''' + 课程 + ''' then 分数 else 0 end) [' + 课程 + ']'
    from (select distinct 课程 from tb) as a
    set @sql = @sql + ' from tb group by 姓名'
    exec(@sql) --SQL SERVER 2005 静态SQL。
    select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b--SQL SERVER 2005 动态SQL。
    declare @sql varchar(8000)
    select @sql = isnull(@sql + '],[' , '') + 课程 from tb group by 课程
    set @sql = '[' + @sql + ']'
    exec ('select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b')---------------------------------/*
    问题:在上述结果的基础上加平均分,总分,得到如下结果:
    姓名 语文 数学 物理 平均分 总分 
    ---- ---- ---- ---- ------ ----
    李四 74   84   94   84.00  252
    张三 74   83   93   83.33  250
    */--SQL SERVER 2000 静态SQL。
    select 姓名 姓名,
      max(case 课程 when '语文' then 分数 else 0 end) 语文,
      max(case 课程 when '数学' then 分数 else 0 end) 数学,
      max(case 课程 when '物理' then 分数 else 0 end) 物理,
      cast(avg(分数*1.0) as decimal(18,2)) 平均分,
      sum(分数) 总分
    from tb
    group by 姓名--SQL SERVER 2000 动态SQL。
    declare @sql varchar(8000)
    set @sql = 'select 姓名 '
    select @sql = @sql + ' , max(case 课程 when ''' + 课程 + ''' then 分数 else 0 end) [' + 课程 + ']'
    from (select distinct 课程 from tb) as a
    set @sql = @sql + ' , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名'
    exec(@sql) --SQL SERVER 2005 静态SQL。
    select m.* , n.平均分 , n.总分 from
    (select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b) m,
    (select 姓名 , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名) n
    where m.姓名 = n.姓名--SQL SERVER 2005 动态SQL。
    declare @sql varchar(8000)
    select @sql = isnull(@sql + ',' , '') + 课程 from tb group by 课程
    exec ('select m.* , n.平均分 , n.总分 from
    (select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b) m , 
    (select 姓名 , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名) n
    where m.姓名 = n.姓名')drop table tb ------------------
    ------------------/*
    问题:如果上述两表互相换一下:即表结构和数据为:
    姓名 语文 数学 物理
    张三 74  83  93
    李四 74  84  94
    想变成(得到如下结果): 
    姓名 课程 分数 
    ---- ---- ----
    李四 语文 74
    李四 数学 84
    李四 物理 94
    张三 语文 74
    张三 数学 83
    张三 物理 93
    --------------
    */create table tb(姓名 varchar(10) , 语文 int , 数学 int , 物理 int)
    insert into tb values('张三',74,83,93)
    insert into tb values('李四',74,84,94)
    go--SQL SERVER 2000 静态SQL。
    select * from
    (
     select 姓名 , 课程 = '语文' , 分数 = 语文 from tb 
     union all
     select 姓名 , 课程 = '数学' , 分数 = 数学 from tb
     union all
     select 姓名 , 课程 = '物理' , 分数 = 物理 from tb
    ) t
    order by 姓名 , case 课程 when '语文' then 1 when '数学' then 2 when '物理' then 3 end--SQL SERVER 2000 动态SQL。
    --调用系统表动态生态。
    declare @sql varchar(8000)
    select @sql = isnull(@sql + ' union all ' , '' ) + ' select 姓名 , [课程] = ' + quotename(Name , '''') + ' , [分数] = ' + quotename(Name) + ' from tb'
    from syscolumns 
    where name! = N'姓名' and ID = object_id('tb') --表名tb,不包含列名为姓名的其它列
    order by colid asc
    exec(@sql + ' order by 姓名 ')--SQL SERVER 2005 动态SQL。
    select 姓名 , 课程 , 分数 from tb unpivot (分数 for 课程 in([语文] , [数学] , [物理])) t--SQL SERVER 2005 动态SQL,同SQL SERVER 2000 动态SQL。--------------------
    /*
    问题:在上述的结果上加个平均分,总分,得到如下结果:
    姓名 课程   分数
    ---- ------ ------
    李四 语文   74.00
    李四 数学   84.00
    李四 物理   94.00
    李四 平均分 84.00
    李四 总分   252.00
    张三 语文   74.00
    张三 数学   83.00
    张三 物理   93.00
    张三 平均分 83.33
    张三 总分   250.00
    ------------------
    */select * from
    (
     select 姓名 as 姓名 , 课程 = '语文' , 分数 = 语文 from tb 
     union all
     select 姓名 as 姓名 , 课程 = '数学' , 分数 = 数学 from tb
     union all
     select 姓名 as 姓名 , 课程 = '物理' , 分数 = 物理 from tb
     union all
     select 姓名 as 姓名 , 课程 = '平均分' , 分数 = cast((语文 + 数学 + 物理)*1.0/3 as decimal(18,2)) from tb
     union all
     select 姓名 as 姓名 , 课程 = '总分' , 分数 = 语文 + 数学 + 物理 from tb
    ) t
    order by 姓名 , case 课程 when '语文' then 1 when '数学' then 2 when '物理' then 3 when '平均分' then 4 when '总分' then 5 enddrop table tb
      

  2.   

    部分资料如下: 
    doc_no rev  type style    mat    sup   component   unit     cons 
    T001     1   A   SS0001   M001   DD01   CB          M         10 
    T001     2   A   SS0001   M001   DD01   CB          M         11 
    T001     2   A   SS0001   M002   DD01   CB          M         10 
    T001     3   A   SS0001   M001   DD01   CB          M         10 
    T001     3   A   SS0001   M002   DD01   CB          M         10 
    T001     3   A   SS0001   M002   DD01   DC          M         9 
     
    T001     4   B   SS0001   M001   DD01   CB          M         12 
    T001     5   B   SS0001   M001   DD01   CB          M         13 
    T001     6   B   SS0001   M003   DD01   CB          M         13 
    T001     6   B   SS0001   M001   DD01   CB          M         13 T001     7   C   SS0001   M001   DD01   CB          M         12 
    T001     8   C   SS0001   M001   DD01   CB          M         13 
    T001     9   C   SS0001   M001   DD01   CB          M         13 
    T001     10  C   SS0001   M001   DD01   CB          M         14 
    T001     10  C   SS0001   M002   DD01   CB          M         9 1.取款ss0001的同一type(只有ABC三种)的最大rev的物料的con. 
    2. 如果mat唯一, 根据mat取用量, 如果不唯一, 根据mat和component取各type的cons. 
    3. 如上资料结果如下: doc_no style   mat   sup   component  unit   A_cons  B_cons  C_cons 
    T001   SS0001  M001  DD01   CB          M      10     13      14 
    T001   SS0001  M002  DD01   CB          M      10             9 
    T001   SS0001  M002  DD01   DC          M      9 
    T001   SS0001  M003  DD01   CB          M             13 不知道再发一次是否对齐了
      

  3.   

    doc_no style mat sup component unit A_cons B_cons C_cons 
    T001   SS0001 M001 DD01 CB          M      10 13 14 
    T001   SS0001 M002 DD01 CB          M      10 9 
    T001   SS0001 M002 DD01 DC          M      9 
    T001   SS0001 M003 DD01 CB          M              13 采用游标进行处理;
     
       
      

  4.   

    先谢过!2. 如果mat唯一, 根据mat取cons; 如果不唯一, 根据mat和component取各type的cons. 
    如m001在三种type最大的rev中都只出现一次, 所以只根据mat取各type的cons
    T001   SS0001  M001  DD01   CB          M      10     13      14  如m002在TYPE A中有两条, 此时还要区分component取各type用量cons
    所以在结果中有:
    T001   SS0001  M002  DD01   CB          M      10             9  
    T001   SS0001  M002  DD01   DC          M      9  
      

  5.   

    --> 测试数据: #T
    if object_id('tempdb.dbo.#T') is not null drop table #T
    create table #T (doc_no varchar(4),rev int,type varchar(1),style varchar(6),mat varchar(4),sup varchar(4),component varchar(2),unit varchar(1),cons int)
    insert into #T
    select 'T001',1,'A','SS0001','M001','DD01','CB','M',10 union all
    select 'T001',2,'A','SS0001','M001','DD01','CB','M',11 union all
    select 'T001',2,'A','SS0001','M002','DD01','CB','M',10 union all
    select 'T001',3,'A','SS0001','M001','DD01','CB','M',10 union all
    select 'T001',3,'A','SS0001','M002','DD01','CB','M',10 union all
    select 'T001',3,'A','SS0001','M002','DD01','DC','M',9 union all
    select 'T001',4,'B','SS0001','M001','DD01','CB','M',12 union all
    select 'T001',5,'B','SS0001','M001','DD01','CB','M',13 union all
    select 'T001',6,'B','SS0001','M003','DD01','CB','M',13 union all
    select 'T001',6,'B','SS0001','M001','DD01','CB','M',13 union all
    select 'T001',7,'C','SS0001','M001','DD01','CB','M',12 union all
    select 'T001',8,'C','SS0001','M001','DD01','CB','M',13 union all
    select 'T001',9,'C','SS0001','M001','DD01','CB','M',13 union all
    select 'T001',10,'C','SS0001','M001','DD01','CB','M',14 union all
    select 'T001',10,'C','SS0001','M002','DD01','CB','M',9
    ;
    with T as
    (
    select * from #T t where rev = (select max(rev) from #T where style=t.style and type=t.type and mat=t.mat)
    )
    select * from
    (select doc_no,style,mat,sup,component,unit,cons,type from T) a
    pivot
    (max(cons) for type in (A,B,C)) b/*
    doc_no style  mat  sup  component unit A           B           C
    ------ ------ ---- ---- --------- ---- ----------- ----------- -----------
    T001   SS0001 M001 DD01 CB        M    10          13          14
    T001   SS0001 M002 DD01 CB        M    10          NULL        9
    T001   SS0001 M002 DD01 DC        M    9           NULL        NULL
    T001   SS0001 M003 DD01 CB        M    NULL        13          NULL
    */
      

  6.   

    --> 测试数据: #T
    if object_id('tempdb.dbo.#T') is not null drop table #T
    create table #T (doc_no varchar(4),rev int,type varchar(1),style varchar(6),mat varchar(4),sup varchar(4),component varchar(2),unit varchar(1),cons int)
    insert into #T
    select 'T001',1,'A','SS0001','M001','DD01','CB','M',10 union all
    select 'T001',2,'A','SS0001','M001','DD01','CB','M',11 union all
    select 'T001',2,'A','SS0001','M002','DD01','CB','M',10 union all
    select 'T001',3,'A','SS0001','M001','DD01','CB','M',10 union all
    select 'T001',3,'A','SS0001','M002','DD01','CB','M',10 union all
    select 'T001',3,'A','SS0001','M002','DD01','DC','M',9 union all
    select 'T001',4,'B','SS0001','M001','DD01','CB','M',12 union all
    select 'T001',5,'B','SS0001','M001','DD01','CB','M',13 union all
    select 'T001',6,'B','SS0001','M003','DD01','CB','M',13 union all
    select 'T001',6,'B','SS0001','M001','DD01','CB','M',13 union all
    select 'T001',7,'C','SS0001','M001','DD01','CB','M',12 union all
    select 'T001',8,'C','SS0001','M001','DD01','CB','M',13 union all
    select 'T001',9,'C','SS0001','M001','DD01','CB','M',13 union all
    select 'T001',10,'C','SS0001','M001','DD01','CB','M',14 union all
    select 'T001',10,'C','SS0001','M002','DD01','CB','M',9
    ;
    -->2005
    with T as
    (
    select * from #T t where rev = (select max(rev) from #T where style=t.style and type=t.type and mat=t.mat)
    )
    select doc_no,style,mat,sup,component,unit,A_Cons=A,B_Cons=B,C_Cons=C from
    (select doc_no,style,mat,sup,component,unit,cons,type from T) a
    pivot
    (max(cons) for type in (A,B,C)) b-->2000
    select
    doc_no,style,mat,sup,component,unit,
    A_Cons=max(case type when 'A' then cons end),
    B_Cons=max(case type when 'B' then cons end),
    C_Cons=max(case type when 'C' then cons end)
    from
    (select * from #T t where rev = (select max(rev) from #T where style=t.style and type=t.type and mat=t.mat)) t
    group by doc_no,style,mat,sup,component,unit/*
    doc_no style  mat  sup  component unit A_Cons      B_Cons      C_Cons
    ------ ------ ---- ---- --------- ---- ----------- ----------- -----------
    T001   SS0001 M001 DD01 CB        M    10          13          14
    T001   SS0001 M002 DD01 CB        M    10          NULL        9
    T001   SS0001 M002 DD01 DC        M    9           NULL        NULL
    T001   SS0001 M003 DD01 CB        M    NULL        13          NULL
    */
      

  7.   

    Limpire 很好理解分析逻辑能力,让我很是佩服。
      

  8.   

    Limpire的确很强
    能否再帮下?
    select 中需要doc_no,但不需要按doc_no分组
    doc_no可任显示其中的一个.
      

  9.   

    select
        doc_no=max(doc_no),style,mat,sup,component,unit,
        A_Cons=max(case type when 'A' then cons end),
        B_Cons=max(case type when 'B' then cons end),
        C_Cons=max(case type when 'C' then cons end)
    from
        (select * from #T t where rev = (select max(rev) from #T where style=t.style and type=t.type and mat=t.mat)) t
    group by style,mat,sup,component,unit
      

  10.   


    2. 如果mat唯一, 根据mat取用量, 如果不唯一, 根据mat和component取各type的cons. 
    如m0001和m0003是唯一的, m0002不唯一T001     3   A   SS0001   M001   DD01   CB          M         10 
      
     T001     6   B   SS0001   M003   DD01   CB          M         13  
    T001     6   B   SS0001   M001   DD01   DC          M         13  T001     10  C   SS0001   M001   DD01   SS          M         14  因为在rev 3, 6, 10中只有一条是m001, 即使component不同仍显示结果如下:T001   SS0001 M001 DD01     CB        M    10          13          14
    component任取其一.
      

  11.   

    doc_no rev  type style    mat    sup   component   unit     cons  
    T001     1   A   SS0001   M001   DD01   CB          M         10  
    T001     2   A   SS0001   M001   DD01   CB          M         11  
    T001     2   A   SS0001   M002   DD01   CB          M         10  
    T001     3   A   SS0001   M001   DD01   CB          M         10  
    T001     3   A   SS0001   M002   DD01   CB          M         10  
    T001     3   A   SS0001   M002   DD01   DC          M         9  
      
    T001     4   B   SS0001   M001   DD01   CB          M         12  
    T001     5   B   SS0001   M001   DD01   CB          M         13  
    T001     6   B   SS0001   M003   DD01   CB          M         13  
    T001     6   B   SS0001   M001   DD01   DC          M         13  T001     7   C   SS0001   M001   DD01   CB          M         12  
    T001     8   C   SS0001   M001   DD01   CB          M         13  
    T001     9   C   SS0001   M001   DD01   CB          M         13  
    T001     10  C   SS0001   M001   DD01   SS          M         14  
    T001     10  C   SS0001   M002   DD01   CB          M         9  如上资料结果如下:  doc_no style   mat   sup   component  unit   A_cons  B_cons  C_cons  
    T001   SS0001  M001  DD01   CB          M      10     13      14  
    T001   SS0001  M002  DD01   CB          M      10             9  
    T001   SS0001  M002  DD01   DC          M      9  
    T001   SS0001  M003  DD01   CB          M             13  
    和上面的差不多, 只是M0001对应的component在各rev中不一样.  
    由于M001在REV3, 6, 10中都只有唯一一条, 虽然component不一样, 但结果只有一条, component取其一.
    T001   SS0001  M001  DD01   CB          M      10     13      14  M002由于在rev3中有两条, 所以要根据component进一步判断.于是结果有两条:
    T001   SS0001  M002  DD01   CB          M      10             9  
    T001   SS0001  M002  DD01   DC          M      9 
      

  12.   

    上面看起来有点别的意味. 不过没关系,作为新手, 对别人的反应都微微一笑Limpire大虾, 明天来给你分. 先谢过.
      

  13.   


    create table #T (doc_no varchar(4),rev int,type varchar(1),style varchar(6),mat varchar(4),sup varchar(4),component varchar(2),unit varchar(1),cons int)
    insert into #T
    select 'T001',1,'A','SS0001','M001','DD01','CB','M',10 union all
    select 'T001',2,'A','SS0001','M001','DD01','CB','M',11 union all
    select 'T001',2,'A','SS0001','M002','DD01','CB','M',10 union all
    select 'T001',3,'A','SS0001','M001','DD01','CB','M',10 union all
    select 'T001',3,'A','SS0001','M002','DD01','CB','M',10 union all
    select 'T001',3,'A','SS0001','M002','DD01','DC','M',9 union all
    select 'T001',4,'B','SS0001','M001','DD01','CB','M',12 union all
    select 'T001',5,'B','SS0001','M001','DD01','CB','M',13 union all
    select 'T001',6,'B','SS0001','M003','DD01','CB','M',13 union all
    select 'T001',6,'B','SS0001','M001','DD01','DC','M',13 union all
    select 'T001',7,'C','SS0001','M001','DD01','CB','M',12 union all
    select 'T001',8,'C','SS0001','M001','DD01','CB','M',13 union all
    select 'T001',9,'C','SS0001','M001','DD01','CB','M',13 union all
    select 'T001',10,'C','SS0001','M001','DD01','SS','M',14 union all
    select 'T001',10,'C','SS0001','M002','DD01','CB','M',9go
    /*
    doc_no style   mat   sup   component  unit   A_cons  B_cons  C_cons   
    T001   SS0001  M001  DD01   CB          M      10     13      14   
    T001   SS0001  M002  DD01   CB          M      10             9   
    T001   SS0001  M002  DD01   DC          M      9   
    T001   SS0001  M003  DD01   CB          M             13   
    */
     select
        doc_no=max(doc_no),style,mat,sup,component1,unit,
        A_Cons=isnull(max(case type when 'A' then cons end),''),
        B_Cons=isnull(max(case type when 'B' then cons end),''),
        C_Cons=isnull(max(case type when 'C' then cons end),'')
    from(
    select *,case when type <> 'A' and not exists(select 1 from #t where  style=t.style and type<>t.type and mat=t.mat and component = t.component)
             then isnull((select  min(component)  from #t where  style=t.style   and mat=t.mat ) ,'sf')
             else component end as component1
    from #T t where rev = (select max(rev) from #T where style=t.style and type=t.type and mat=t.mat)) t
    group by style,mat,component1,sup,unit/*
    doc_no style  mat  sup  component1 unit A_Cons      B_Cons      C_Cons      
    ------ ------ ---- ---- ---------- ---- ----------- ----------- ----------- 
    T001   SS0001 M001 DD01 CB         M    10          13          14
    T001   SS0001 M002 DD01 CB         M    10          0           9
    T001   SS0001 M002 DD01 DC         M    9           0           0
    T001   SS0001 M003 DD01 CB         M    0           13          0(所影响的行数为 4 行)
    */if object_id('tempdb.dbo.#T') is not null drop table #T
      

  14.   

    --> 测试数据: #T
    if object_id('tempdb.dbo.#T') is not null drop table #T
    create table #T (doc_no varchar(4),rev int,type varchar(1),style varchar(6),mat varchar(4),sup varchar(4),component varchar(2),unit varchar(1),cons int)
    insert into #T
    select 'T101',1,'A','SS0001','M001','DD01','CB','M',10 union all
    select 'T101',2,'A','SS0001','M001','DD01','CB','M',11 union all
    select 'T101',2,'A','SS0001','M002','DD01','CB','M',10 union all
    select 'T101',3,'A','SS0001','M001','DD01','CB','M',10 union all
    select 'T101',3,'A','SS0001','M002','DD01','CB','M',10 union all
    select 'T101',3,'A','SS0001','M002','DD01','DC','M',9 union all
    select 'T101',4,'B','SS0001','M001','DD01','CB','M',12 union all
    select 'T101',5,'B','SS0001','M001','DD01','CB','M',13 union all
    select 'T101',6,'B','SS0001','M003','DD01','CB','M',13 union all
    select 'T101',6,'B','SS0001','M001','DD01','DC','M',13 union all
    select 'T101',7,'C','SS0001','M001','DD01','CB','M',12 union all
    select 'T101',8,'C','SS0001','M001','DD01','CB','M',13 union all
    select 'T101',9,'C','SS0001','M001','DD01','CB','M',13 union all
    select 'T101',10,'C','SS0001','M001','DD01','SS','M',14 union all
    select 'T101',10,'C','SS0001','M002','DD01','CB','M',9
    ;
    -->2005
    with
    T1 as
    (
    select * from #T t where rev = (select max(rev) from #T where style=t.style and type=t.type and mat=t.mat)
    ),
    T2 as
    (
    select style,mat,component=min(component),cn1=count(distinct rev),cn2=count(rev) from T1 group by style,mat
    )
    select
    doc_no=max(a.doc_no),a.style,a.mat,a.sup,
    component=case when b.cn1=b.cn2 then b.component else a.component end,
    a.unit,
    A_Cons=max(case type when 'A' then a.cons end),
    B_Cons=max(case type when 'B' then a.cons end),
    C_Cons=max(case type when 'C' then a.cons end)
    from
    T1 a join T2 b on a.style=b.style and a.mat=b.mat
    group by
    a.style,a.mat,a.sup,case when b.cn1=b.cn2 then b.component else a.component end,a.unit/*
    doc_no style  mat  sup  component unit A_Cons      B_Cons      C_Cons
    ------ ------ ---- ---- --------- ---- ----------- ----------- -----------
    T101   SS0001 M001 DD01 CB        M    10          13          14
    T101   SS0001 M002 DD01 CB        M    10          NULL        9
    T101   SS0001 M002 DD01 DC        M    9           NULL        NULL
    T101   SS0001 M003 DD01 CB        M    NULL        13          NULL
    */--> 2000不写了,把T1,T2放到临时表或用子查询,个人偏向用临时表,太多子查询可读性差。