商品名称 型号 颜色 价格
手机 A 红 60
手机 B 蓝 55 商品名称 型号 颜色 价格区间
电脑 D 白 100 通过SQL 手机 3种 红,蓝 40-80
手机 A 红 80 电脑 2种 白,黄 90-105
电脑 E 白 105
手机 C 红 40
电脑 D 黄 90 如上,我有一个产品表,现在想通过SQL语句将商品进行一个统计,即所有手机,有几种型号,颜色有几种就列几种,价格区间是多少。
求SQL语句。

解决方案 »

  1.   

    你的期望结果是什么?最好给出完整的表结构,测试数据,计算方法和正确结果.否则耽搁的是你宝贵的时间。
    如果有多表,表之间如何关联?
    如何更有效地在SQL Server论坛上提问
    http://topic.csdn.net/u/20100716/19/6f132f16-20e4-418c-8dee-b99d5f86d320.html?75910
      

  2.   

    如果仅仅是个行列转换就参考如下的例.
    /*
    标题:普通行列转换(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 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
      

  3.   


    select 商品名称,count(distinct 颜色) as 颜色种类,
           stuff((select ','+颜色 from tb where 商品名称 = t.商品名称 for xml path('')),1,1,) as 颜色具体,
           count(distinct 价格) as 价目种类,
           stuff((select ','+ltrim(价格) from tb where 商品名称 = t.商品名称 for xml path('')),1,1,) as 价格具体,
           ltrim(min(价格)) + '-' + ltrim(max(价格))  as 价格区间
    from tb t
    group by 商品名称
      

  4.   


    -2000create function dbo.f_str(@pro varchar(50))
    returns varchar(8000)
    as
    begin
        declare @r varchar(8000)
        set @r = ''
        select @r = @r + ',' + 颜色
        from tb
        where 商品名称 = @pro
        return stuff(@r, 1, 1, '')
    end
    goselect 商品名称,count(distinct 颜色) as 颜色种类,
           dbo.f_str(商品名称) as 颜色具体,
           count(distinct 价格) as 价目种类,
           ltrim(min(价格)) + '-' + ltrim(max(价格))  as 价格区间
    from tb t
    group by 商品名称
      

  5.   

    我表述的不是很清楚,新地址http://topic.csdn.net/u/20110414/10/152d3a1e-c4a6-4855-a2fc-73feb64af439.html一共200分,谢谢各位。
      

  6.   


    create table tb (商品名称 char(10),型号 char(5),颜色 char(10),价格 int)
    insert into tb
    select '手机', 'A', '红', 60 union
    select '手机', 'B', '蓝', 55 union
    select '电脑', 'D', '白', 100 union
    select '手机', 'A', '红', 80 union
    select '电脑', 'E', '白', 105 union
    select '手机', 'C', '红', 40 union
    select '电脑', 'D', '黄', 90 select 商品名称,型号=count(distinct 型号),
           颜色=stuff((select ','+颜色 from tb where 商品名称=a.商品名称 group by 颜色 for xml path('')),1,1,''),
          价格区间=rtrim(min(价格))+'-'+rtrim(max(价格))
    from tb a group by 商品名称/*
    商品名称       型号          颜色        价格区间
    ---------- ----------- -----------------------------------------------------------
    电脑         2           白        ,黄   90-105
    手机         3           红        ,蓝  40-80  
      

  7.   

    各位,总是报
    服务器: 消息 170,级别 15,状态 1,行 2
    第 2 行: 'xml' 附近有语法错误。
      

  8.   

    你是sql 2000的吧?需要使用函数,参考你另外一贴.
      

  9.   

    你的SQL是2000,不写函数没办法的!写把!