有表A
lx dk lh
手表 A 1
手表 A 2
手表 B 1
手表 C 1
计算器 B 2
计算器 C 1
计算器 C 2
计算器 A 2
闹钟 B 2
闹钟 A 2
闹钟 C 1
闹钟 C 3要得到下表,如何写SQL
手表 计算器 闹钟
A 2 1 1 (注:DK为A的汇总)
1 1 (注:DK为A,LH为1的汇总)
2 1 1 1 (以下相同,DK数量未定,LH数据未定)
=============================
B 1 1 1
1 1
2 1 1
=============================
C 1 2 2
1 1 1 1
2 1
3 1
=============================
合计 4 4 4

解决方案 »

  1.   

    就是先按DK统计,再接DK+LH统计,最后再一个合计
      

  2.   

    就是先统计DK为A的项目,再统计DK为A,LH为1的项目
    最后合计
      

  3.   

    /*SQL Server2000*/
    --测试表
    create table abinnet (
    lx char(10),
    dk char(10),
    lh char(10))
    --插入数据
    insert into abinnet 
    select '手表','A','1'
    union
    select '手表','A','2'
    union
    select '手表','B','1'
    union
    select '手表','C','1'
    union
    select '计算器','B','2'
    union
    select '计算器','C','1'
    union
    select '计算器','C','2'
    union
    select '计算器','A','2'
    union
    select '闹钟','B','2'
    union
    select '闹钟','A','2'
    union
    select '闹钟','C','1'
    union
    select '闹钟','C','3'
    --行列转换
    select dk,lh,isnull(手表,0) 手表 ,isnull(闹钟,0) 闹钟,isnull(计算器,0) 计算器 
    into #temp from 
    (select dk,lh,手表=
    max(case
     when lx='手表' then 1  
    end),
    闹钟=
    max(case
     when lx='闹钟' then 1
    end),
    计算器=
    max(case
     when lx='计算器' then  1
    end)
    from abinnet 
    group by lh,dk) a
    order by dk,lh--加入分组统计
    select lh,手表,闹钟,计算器 from
    (select * from #temp
    union
    select dk,dk [lh],sum(手表) 手表,sum(闹钟) 闹钟,sum(计算器) 计算器 from #temp group by dk)a
    order by dk
    --删除测试环境
    drop table abinnet 
    drop table #temp/*结果
    1       1 0 0
    2       1 1 1
    A       2 1 1
    1       1 0 0
    2       0 1 1
    B       1 1 1
    1       1 1 1
    2       0 0 1
    3       0 1 0
    C       1 2 2
    */
      

  4.   

    当脚本中出现了,记录中提的 如 手表,闹钟, a ,b,c ,1,2,3 这些字样都是不对的.
      

  5.   

    To:jinjazz(人雅的标记--落寞刺客) 请教一下如果表中不止'手表','闹钟','计算器' 这三种类型,如何修改上面的SQL
      

  6.   

    >>请教一下如果表中不止'手表','闹钟','计算器' 这三种类型,如何修改上面的SQL>>xhh_88(三友):你的意思和楼上兄弟的差不多吧
    可以用动态sql,可以参考:
    http://community.csdn.net/Expert/topic/3417/3417326.xml?temp=.8555414
      

  7.   

    /*SQL Server2000*/
    --测试表
    create table abinnet (
    lx char(10),
    dk char(10),
    lh char(10))
    --插入数据
    insert into abinnet 
    select '手表','A','1'
    union
    select '手表','A','2'
    union
    select '手表','B','1'
    union
    select '手表','C','1'
    union
    select '计算器','B','2'
    union
    select '计算器','C','1'
    union
    select '计算器','C','2'
    union
    select '计算器','A','2'
    union
    select '闹钟','B','2'
    union
    select '闹钟','A','2'
    union
    select '闹钟','C','1'
    union
    select '闹钟','C','3'
    --动态语法,分析一下其实没什么高深,一个select语句而已
    DECLARE @SQL VARCHAR(8000)
    SET @SQL='SELECT dk,lh'
    SELECT @SQL= @SQL+ ',MAX(CASE WHEN lx = ''' + lx + ''' THEN 1 else 0 END) [' +lx + ']' FROM (SELECT DISTINCT lx FROM abinnet) A
    SET @SQL=@SQL+' into ##temp FROM abinnet GROUP BY dk,lh 'EXEC (@SQL)--求汇总,原理与上面相似
    set @sql='select * from ##temp union select dk,dk [lh] '
    select @sql=@sql+', sum('+lx+') ['+lx+']' from (select distinct lx from abinnet) a
    set @sql=@sql+'from ##temp group by dk'--我没有加入总汇总,你如果理解了可以自己尝试写一下哦exec( @SQL)/*结果,多了个字段?没所谓吧,报表里不要显示--要不,你愿意再用动态sql取一下dk     lh   计算器  闹钟 手表
    A         1          0 0 1
    A         2          1 1 1
    A         A          1 1 2
    B         1          0 0 1
    B         2          1 1 0
    B         B          1 1 1
    C         1          1 1 1
    C         2          1 0 0
    C         3          0 1 0
    C         C          2 2 1 */
    --删除测试环境
    drop table abinnet 
    drop table ##temp
      

  8.   

    to: xhh_88(三友)这次你能满意了吧,没有涉及任何记录里面的内容to:  luke5678(奇异)
    30号那天上海交通管制,我们不到3点都勒令下班了..家里由于一点小问题帐户上不来,到今天才能上。所以来晚了,你可以仔细比较一下上面连接那贴和这贴的差别,我不敢保证我的方法是最好的,但是我敢保证我的方法是很有用的(可惜看见邹建我就手发抖,致使SQL区还是个一毛用户)。那贴由于book具有不确定性,所以我用一条语句为他们没人都分配了一个序号,动态语句的标准按照那个序号来做,而这贴应为要加汇总,要多次用到动态赋值,所以两贴个有难度,但是核心语句都一样...SQL区还有过一个类似的例子你可以参考:
    http://community.csdn.net/Expert/topic/2767/2767759.xml?temp=.1236078
      

  9.   

    PS:oracle用decode语句也可达到和case相同的效果,即便是access也有专门做交叉的语句TransForm,至于另外一贴要求的用SQL92标准语法来实现,我想是无能为力的,否则已access的吝啬程度也不会扩展一个专门的语句来
      

  10.   

    谢谢 jinjazz(人雅的标记--落寞刺客)大哥,学习!
      

  11.   

    回:jinjazz(人雅的标记--落寞刺客)
    非常感谢你的帮助,我是个SQL初学者,能帮我解释一下你帮我写的意思吗?--动态语法,分析一下其实没什么高深,一个select语句而已
    DECLARE @SQL VARCHAR(8000)
    SET @SQL='SELECT dk,lh'
    SELECT @SQL= @SQL+ ',MAX(CASE WHEN lx = ''' + lx + ''' THEN 1 else 0 END) [' +lx + ']' FROM (SELECT DISTINCT lx FROM abinnet) A
    SET @SQL=@SQL+' into ##temp FROM abinnet GROUP BY dk,lh 'EXEC (@SQL)--求汇总,原理与上面相似
    set @sql='select * from ##temp union select dk,dk [lh] '
    select @sql=@sql+', sum('+lx+') ['+lx+']' from (select distinct lx from abinnet) a
    set @sql=@sql+'from ##temp group by dk'
    如果表A再增加两
    有表A                  (新增的两列)
    lx dk lh    mj    zt
    手表 A 1     100   yy
    手表 A 2     200   yy
    手表 B 1     150   nn
    手表 C 1     210   nn
    计算器 B 2     115   yy 
    计算器 C 1     65    yy
    计算器 C 2     154   nn
    计算器 A 2     121   nn
    闹钟 B 2     141   nn
    闹钟 A 2     151   yy
    闹钟 C 1     114   yy
    闹钟 C 3     111   nn要得到下表,加一个条件:zt = 'yy' 如何改原来的SQL
    手表 计算器 闹钟
            sl  mj    sl  mj   sl  mj
    A 2  300 1 121 1 151 (注:DK为A的汇总)
    1 1  100 (注:DK为A,LH为1的汇总)
    2 1  200 1 121 1 151 (以下相同,DK数量未定,LH数据未定)
    =============================
    B 1  ... 1 1
    1 1
    2 1 1
    =============================
    C 1 2 2
    1 1 1 1
    2 1
    3 1
    =============================
    合计 4 4 4