表结构如下:
表A:
name string 
date datetime
07:00 bool
08:00 bool

表数据:
name date 07:00 08:00 09:00 10:00 11:00 12:00
gm 2012-06-20 1 0 1 0 1 0
gm 2012-06-11 1 0 1 0 0 0
求教:
按照每个time时间的bool值,只取true,如何让查询结果转变成为:name date time
gm 2012-06-20 07:00
gm 2012-06-20 09:00
gm 2012-06-20 11:00
gm 2012-06-11 07:00
gm 2012-06-11 09:00
这样做是否可行?请教大家。

解决方案 »

  1.   


    --> 测试数据:[test]
    if object_id('[test]') is not null 
    drop table [test]
    create table [test](
    [name] varchar(2),
    [date] datetime,
    [07:00] int,
    [08:00] int,
    [09:00] int,
    [10:00] int,
    [11:00] int,
    [12:00] int
    )
    go
    insert [test]
    select 'gm','2012-06-20',1,0,1,0,1,0 union all
    select 'gm','2012-06-11',1,0,1,0,0,0
    go
    declare @s nvarchar(4000)
    select @s=isnull(@s+' union all ','')+'select [name],[date],[time]
    ='+quotename(Name,'''')
    +',[value]='+quotename(Name)+' from test'
    from syscolumns where ID=object_id('test') 
    and Name not in('name','date')
    order by Colid
    exec('select name,convert(varchar(10),date,120) as date,time from(
    select * from ('+@s+')t  )m where value=1 order by [name],[date]')
    /*
    name date time
    --------------------------------------
    gm 2012-06-11 07:00
    gm 2012-06-11 09:00
    gm 2012-06-20 11:00
    gm 2012-06-20 09:00
    gm 2012-06-20 07:00
    */
      

  2.   

    这个可行,但是一般都不这么做。这样做会复杂很多,对于后期的维护也困难很多。你的情况,一般来说会建两个表
    表1:
    ID Name Date
    1  gm   2012-06-11 
    表2:
    ID ID表1 Time
    1  1     07:00
    2  1     09:00然后用
    select * from 表1
    inner join 表2 ...对于数据库来说,数据结构非常重要,一般情况下要尽可能避免表结构的变化,不然后期的开发就是噩梦。对于你原先的结构,如果只需要对于某一天添加新的时间,你不光要添加新列,而且还要定义每一行(每个)的值,空间不说,也麻烦很多。
    如果定义成两个表,你只需要在表2中添加一行数据就行。表结构根本就不用动。
      

  3.   


    请问我建了哪两个表??
    我只是利用了系统表而已,你的表结构怎么变不影响这个语句这就是行列转换问题,目前的解决方法就是这些:--行列互转
    --摘自中国风博客,引用请标明内容来源
    --1、行换列
    if object_id('Class') is not  null
        drop table Class
    Go
    Create table Class(
    [Student] nvarchar(2),
    [Course] nvarchar(2),
    [Score] int)
    Insert Class
    select N'张三',N'语文',78 union all
    select N'张三',N'数学',87 union all
    select N'张三',N'英语',82 union all
    select N'张三',N'物理',90 union all
    select N'李四',N'语文',65 union all
    select N'李四',N'数学',77 union all
    select N'李四',N'英语',65 union all
    select N'李四',N'物理',85 
    Go--2000方法:
    --动态:
    declare @s nvarchar(4000)
    set @s=''
    Select @s=@s+','+quotename([Course])+'=max(case when [Course]='    
       
        +quotename([Course],'''')+' then [Score] else 0 end)'
    from 
        Class group by[Course]
    --select @s
    exec('select [Student]'+@s+' from Class group by [Student]')
    --生成静态:
    select 
        [Student],
        [数学]=max(case when [Course]='数学' then [Score] else 0 end),
        [物理]=max(case when [Course]='物理' then [Score] else 0 end),
        [英语]=max(case when [Course]='英语' then [Score] else 0 end),
        [语文]=max(case when [Course]='语文' then [Score] else 0 end) 
    from 
        Class 
    group by [Student]
    GO
    --动态:declare @s nvarchar(4000)
    Select @s=isnull(@s+',','')+quotename([Course]) from Class group by[Course]
    select @s
    exec('select * from Class pivot (max([Score]) for [Course] in('+@s+'))b')--生成静态:
    select * 
    from 
        Class 
    pivot 
        (max([Score]) for [Course] in([数学],[物理],[英语],[语文]))b--生成格式:
    /*
    Student 数学         物理         英语         语文
    ------- ----------- ----------- ----------- -----------
    李四     77          85          65          65
    张三     87          90          82          78(2 行受影响)
    */go
    --加上总成绩(学科平均分)--2000方法:
    --动态:declare @s nvarchar(4000)
    set @s=''
    Select @s=@s+','+quotename([Course])+'=max(case when [Course]='+quotename([Course],'''')+'then [Score] else 0 end)'
    from Class group by[Course]
    exec('select [Student]'+@s+',[总成绩]=sum([Score])  from Class group by [Student]')--加多一列(学科平均分用avg([Score]))生成动态:select 
        [Student],
        [数学]=max(case when [Course]='数学' then [Score] else 0 end),
        [物理]=max(case when [Course]='物理' then [Score] else 0 end),
        [英语]=max(case when [Course]='英语' then [Score] else 0 end),
        [语文]=max(case when [Course]='语文' then [Score] else 0 end),
        [总成绩]=([Score]) --加多一列(学科平均分用avg([Score]))
    from 
        Class 
    group by [Student]go--2005方法:动态:declare @s nvarchar(4000)
    Select  @s=isnull(@s+',','')+quotename([Course]) from Class group by[Course] 
    --isnull(@s+',','') 去掉字符串@s中第一个逗号exec('select [Student],'+@s+',[总成绩] from (select *,[总成绩]=sum([Score])over(partition by [Student]) from Class) a 
    pivot (max([Score]) for [Course] in('+@s+'))b ')--生成静态:select 
        [Student],[数学],[物理],[英语],[语文],[总成绩] 
    from 
        (select *,[总成绩]=sum([Score])over(partition by [Student]) from Class) a --平均分时用avg([Score])
    pivot 
        (max([Score]) for [Course] in([数学],[物理],[英语],[语文]))b 生成格式:/*
    Student 数学         物理         英语         语文         总成绩
    ------- ----------- ----------- ----------- ----------- -----------
    李四     77          85          65          65          292
    张三     87          90          82          78          337(2 行受影响)
    */go--2、列转行
     
    if not object_id('Class') is null
        drop table Class
    Go
    Create table Class([Student] nvarchar(2),[数学] int,[物理] int,[英语] int,[语文] int)
    Insert Class
    select N'李四',77,85,65,65 union all
    select N'张三',87,90,82,78
    Go--2000:动态:declare @s nvarchar(4000)
    select @s=isnull(@s+' union all ','')+'select [Student],[Course]='+quotename(Name,'''')--isnull(@s+' union all ','') 去掉字符串@s中第一个union all
    +',[Score]='+quotename(Name)+' from Class'
    from syscolumns where ID=object_id('Class') and Name not in('Student')--排除不转换的列
    order by Colid
    exec('select * from ('+@s+')t order by [Student],[Course]')--增加一个排序生成静态:
    select * 
    from (select [Student],[Course]='数学',[Score]=[数学] from Class union all 
    select [Student],[Course]='物理',[Score]=[物理] from Class union all 
    select [Student],[Course]='英语',[Score]=[英语] from Class union all 
    select [Student],[Course]='语文',[Score]=[语文] from Class)t 
    order by [Student],[Course]go
    --2005:动态:declare @s nvarchar(4000)
    select @s=isnull(@s+',','')+quotename(Name)
    from syscolumns where ID=object_id('Class') and Name not in('Student') 
    order by Colid
    exec('select Student,[Course],[Score] from Class unpivot ([Score] for [Course] in('+@s+'))b')go
    select 
        Student,[Course],[Score] 
    from 
        Class 
    unpivot 
        ([Score] for [Course] in([数学],[物理],[英语],[语文]))b
    生成格式:
    /*
    Student Course Score
    ------- ------- -----------
    李四     数学     77
    李四     物理     85
    李四     英语     65
    李四     语文     65
    张三     数学     87
    张三     物理     90
    张三     英语     82
    张三     语文     78
    */
      

  4.   


    if object_id('[test]') is not null 
    drop table [test]
    create table [test](
    [name] varchar(2),
    [date] datetime,
    [07:00] int,
    [08:00] int,
    [09:00] int,
    [10:00] int,
    [11:00] int,
    [12:00] int
    )
    go
    insert [test]
    select 'gm','2012-06-20',1,0,1,0,1,0 union all
    select 'gm','2012-06-11',1,0,1,0,0,0
    gowith col as (
    select sc.name
     from syscolumns  sc,sysobjects s where sc.id=s.id   and s.name='test' and sc.name<>'name' and sc.name<>'date'
    )
    select t.name,t.date,c.name as [time]
    from col c,[test] t 
    where (case when( c.[name]='07:00' and t.[07:00]=0 )then  0
          when( c.[name]='08:00' and t.[08:00]=0 )then  0
          when( c.[name]='09:00' and t.[09:00]=0 )then  0
          when( c.[name]='10:00' and t.[10:00]=0 )then  0
          when( c.[name]='11:00' and t.[11:00]=0 )then  0
          when( c.[name]='12:00' and t.[12:00]=0 )then  0
     else 1 end )=1 group by t.name,t.date,c.name   
      

  5.   

    结果
    gm 2012-06-11 00:00:00.000 07:00
    gm 2012-06-11 00:00:00.000 09:00
    gm 2012-06-20 00:00:00.000 07:00
    gm 2012-06-20 00:00:00.000 09:00
    gm 2012-06-20 00:00:00.000 11:00
      

  6.   

    with col as (
    select name from syscolumns where ID=object_id('test') and  name<>'name' and  name<>'date'
    )
    select t.name,t.date,c.name as [time]
    from col c,[test] t 
    where (case when( c.[name]='07:00' and t.[07:00]=0 )then  0
          when( c.[name]='08:00' and t.[08:00]=0 )then  0
          when( c.[name]='09:00' and t.[09:00]=0 )then  0
          when( c.[name]='10:00' and t.[10:00]=0 )then  0
          when( c.[name]='11:00' and t.[11:00]=0 )then  0
          when( c.[name]='12:00' and t.[12:00]=0 )then  0
     else 1 end )=1  
    改进了下。
      

  7.   

    非常感谢TravyLee!由于是程序建库,现阶段没法对表结构做变更,合作方又需要提供这个结果,TravyLee的答案是最理想的,谢谢大家的帮助!