有个数据库表,如下
id    class     flg
1      up1       0
1     down1      1
1      up2       0
1     down2      1
2      up1       0
2     down1      1
2      up2       0
3      up1       0
4      up1       0
5      up1       0
5     down1      1
5      up2       0
5     down2      1要求检索出来的数据,按照flg的判断合并,效果如下:
id    classUp    classDown     
1      up1        down1      
1      up2        down2      
2      up1        down1
2      up2          -
3      up1          -
4      up1          -
5      up1        down1      
5      up2        down2SQL SERVER能做到这样吗? SQL SERVER很多函数都没用过,不了解
求大侠们指点,最好能贴出成功的SQL文。

解决方案 »

  1.   

    用row_number加个行号,或者用临时表加个子增列,按照上一条下一条来关联
    但是如果表中的顺序是乱的话没法弄
      

  2.   

    -------------参考----------------------------假设我们有如下数据表
    ------菜系表------------
    --店名        菜系------
    --澳门豆捞    川菜 
    --澳门豆捞    粤菜 
    --澳门豆捞    闽菜 
    --为民大酒店  鲁菜 
    --为民大酒店  粤菜 
    --为民大酒店  川菜
    ------------------------------执行如下语句
    select 店名,菜系=STUFF((select ','+ltrim(菜系) from 菜系表 where 店名=t.店名 for XML path('')),1,1,'')
    from 菜系表 t
    group by 店名-------结果如下-------------
    --店名        菜系----------
    --澳门豆捞    川菜,闽菜,粤菜
    --为民大酒店  川菜,鲁菜,粤菜
    ------------------------------------------------------------------------------------------------------------------
    Stuff(expression1_Str,startIndex,lengthInt,expression2_Str)函数共有四个参数,
    其功能是将expression1_Str中自startIndex位置起删除lengthInt个字符,然后将expression2插入到expression1_Str中的startIndex位置。startIndex 从1开始
    数据库表中有三个字段,要以xxxx-xxxxxx-xxxxxx的格式输出,其中不满相应位数的,在后面补空格,即把类似23,1234,879这样的三个数以如下形式输出到报表中:23__-1234__-879___的格式输出,标注颜色的下划线一种颜色代表一个空格。 
    STUFF(SPACE(4),1,LEN(‘23’),’23’)+’-’+STUFF(SPACE(6),1,LEN(‘1234’),’1234’)+’-’+ STUFF(SPACE(6),1,LEN(‘879’),’879’),转换结果自然就为23__-1234__-879___了。
    Stuff函数另一种解释
    select stuff('string1',<starting position>,<length to delete from string 1>,'string2')
    示例:
    select stuff('youxiaofeng',2,1,'F')
    从第二个字符开始,删掉一个字符,然后用'F'代替删掉字符的位置,如果不需要删掉字符,则将<length to delete from string 1>设为0即可。
    注意:如果<starting position>或<length to delete from string 1 >是负的,或者<starting position>是大于<string 1>长度的数,则STUFF函数将返回NULL,如果指令的<length to delete from string 1>长于从<starting position>位置到<string 1>结尾的字符数,此函数将<string 1 >在<starting position-1>处截断---------------------------------------------------------------------------
    FOR XML PATH 语句的应用
    大家都知道在SQL Server中利用 FOR XML PATH 语句能够把查询的数据生成XML数据,下面是它的一些应用示例。DECLARE @TempTable table(UserID int , UserName nvarchar(50));
    insert into @TempTable (UserID,UserName) values (1,'a')
    insert into @TempTable (UserID,UserName) values (2,'b')select UserID,UserName from @TempTable FOR XML PATH
    运行这段脚本,将生成如下结果:<row>
    <UserID>1</UserID>
    <UserName>a</UserName>
    </row>
    <row>
    <UserID>2</UserID>
    <UserName>b</UserName>
    </row>
    大家可以看到两行数据生成了两个节点,修改一下PATH的参数:select UserID,UserName from @TempTable FOR XML PATH('lzy')
    再次运行上述脚本,将生成如下的结果:<lzy>
    <UserID>1</UserID>
    <UserName>a</UserName>
    </lzy>
    <lzy>
    <UserID>2</UserID>
    <UserName>b</UserName>
    </lzy>
    可以看到节点变成,其实PATH() 括号内的参数是控制节点名称的,这样的话大家可以看一下如果是空字符串(不是没有参数)会是什么结果?select UserID,UserName from @TempTable FOR XML PATH('')
    执行上面这段脚本将生成结果:<UserID>1</UserID>
    <UserName>a</UserName>
    <UserID>2</UserID>
    <UserName>b</UserName>
    这样就不显示上级节点了,大家知道在 PATH 模式中,列名或列别名被作为 XPath 表达式来处理,也就是说,是列的名字,这样大胆试验一下不给指定列名和别名会是怎么样?select CAST(UserID AS varchar) + '',UserName + '' from @TempTable FOR XML PATH('')
    运行上面这句将生成结果1a2b所有数据都生成一行,而且还没有连接字符,这样的数据可能对大家没有用处,还可以再变化一下:select CAST(UserID AS varchar) + ',',UserName + '',';' from @TempTable FOR XML PATH('')
    生成结果1,a;2,b;大家现在明白了吧,可以通过控制参数来生成自己想要的结果,例如:select '{' + CAST(UserID AS varchar) + ',','"' +UserName + '"','}' from @TempTable FOR XML PATH('')
    生成结果{1,"a"}{2,"b"}还可以生成其他格式,大家可以根据自己需要的格式进行组合。下面是一个数据统计的应用,希望大家可以通过下面的实例想到更多的应用DECLARE @T1 table(UserID int , UserName nvarchar(50),CityName nvarchar(50));
    insert into @T1 (UserID,UserName,CityName) values (1,'a','上海')
    insert into @T1 (UserID,UserName,CityName) values (2,'b','北京')
    insert into @T1 (UserID,UserName,CityName) values (3,'c','上海')
    insert into @T1 (UserID,UserName,CityName) values (4,'d','北京')
    insert into @T1 (UserID,UserName,CityName) values (5,'e','上海')SELECT B.CityName,LEFT(UserList,LEN(UserList)-1) FROM (
    SELECT CityName,
    (SELECT UserName+',' FROM @T1 WHERE CityName=A.CityName FOR XML PATH('')) AS UserList
    FROM @T1 A 
    GROUP BY CityName
    ) B
    生成结果(每个城市的用户名)北京 b,d
    上海 a,c,e
     
      

  3.   


    /*------------------------------------------------------------------
    --  Author : htl258(Tony)
    --  Date   : 2010-04-15 08:38:00
    --  Version: Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86) 
    Jul  9 2008 14:43:34 
    Copyright (c) 1988-2008 Microsoft Corporation
    Developer Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)------------------------------------------------------------------*/
    --> 生成测试数据表:tbIF OBJECT_ID('[tb]') IS NOT NULL
    DROP TABLE [tb]
    GO
    CREATE TABLE [tb]([id] INT,[class] NVARCHAR(10),[flg] NVARCHAR(10))
    INSERT [tb]
    SELECT 1,'up1','0' UNION ALL
    SELECT 1,'down1','1' UNION ALL
    SELECT 1,'up2','0' UNION ALL
    SELECT 1,'down2','1' UNION ALL
    SELECT 2,'up1','0' UNION ALL
    SELECT 2,'down1','1' UNION ALL
    SELECT 2,'up2','0' UNION ALL
    SELECT 3,'up1','0' UNION ALL
    SELECT 4,'up1','0' UNION ALL
    SELECT 5,'up1','0' UNION ALL
    SELECT 5,'down1','1' UNION ALL
    SELECT 5,'up2','0' UNION ALL
    SELECT 5,'down2','1'
    GO
    --SELECT * FROM [tb]-->SQL查询如下:
    ;WITH T AS
    (
     SELECT RN=ROW_NUMBER()OVER(PARTITION BY ID ORDER BY CLASS),* FROM TB WHERE FLG=0
    ),
    T1 AS
    (
     SELECT RN=ROW_NUMBER()OVER(PARTITION BY ID ORDER BY CLASS),* FROM TB WHERE FLG=1
    )
    SELECT ID,CLASS CLASSUP,ISNULL(CLASSDOWN,'--') CLASSDOWN  
    FROM T 
    OUTER APPLY (SELECT CLASS CLASSDOWN FROM T1 WHERE T.RN=RN AND T.ID=ID) B
    /*
    id          classUp    classDown
    ----------- ---------- ----------
    1           up1        down1
    1           up2        down2
    2           up1        down1
    2           up2        --
    3           up1        --
    4           up1        --
    5           up1        down1
    5           up2        down2(8 行受影响)
    */
      

  4.   

    create table tb(id int,class varchar(10),flg int)
    insert tb values(1,'up1',0)
    insert tb values(1,'down1',1)
    insert tb values(1,'up2',0)
    insert tb values(1,'down2',1)
    insert tb values(2,'up1',0)
    insert tb values(2,'down1',1)
    insert tb values(2,'up2',0)
    insert tb values(3,'up1',0)
    insert tb values(4,'up1',0)
    insert tb values(5,'up1',0)
    insert tb values(5,'down1',1)
    insert tb values(5,'up2',0)
    insert tb values(5,'down2',1)
    goselect t1.id,t1.class as classUp,isnull(t2.class,'-') as classDown from tb t1 left join tb t2 
    on t1.id=t2.id and right(t1.class,1)=right(t2.class,1) 
    and ( t2.class like 'down%' )
    where  t1.class like 'up%' drop table tb
    go
    id          classUp    classDown  
    ----------- ---------- ---------- 
    1           up1        down1
    1           up2        down2
    2           up1        down1
    2           up2        -
    3           up1        -
    4           up1        -
    5           up1        down1
    5           up2        down2(所影响的行数为 8 行)
      

  5.   

    select t1.id,t1.class as classUp,isnull(t2.class,'-') as classDown from tb t1 left join tb t2 
    on t1.id=t2.id and right(t1.class,1)=right(t2.class,1) 
    and ( t2.class like 'down%' )
    where  t1.class like 'up%' 
    --引用自楼上
      

  6.   

    问题是我这表里class数据不一定是up1,down1,up2,down2的
    可能是a,b,c,d
    是排序了之后把flg的0,1成对的合并,只有0没有1的"-"显示
    不知道大家明白了没有 - -##
      

  7.   


    可以试下5楼TONY哥的 他的经过了排序 还是那句话 楼主的表结构设计太不合理
      

  8.   

    --------------------SQL Server数据格式化工具-------------------
    ---------------------------------------------------------------
    -- DESIGNER :happycell188(喜喜)
    --       QQ :584738179
    -- Development Tool :Microsoft Visual C++ 6.0    C Language 
    -- FUNCTION :CONVERT DATA TO T-SQL
    ---------------------------------------------------------------
    -- Microsoft SQL Server  2005
    -- Developer Edition on Microsoft Windows XP [版本 5.1.2600]
    ---------------------------------------------------------------
    ---------------------------------------------------------------use test
    go
    if object_id('test.dbo.tb') is not null drop table tb
    -- 创建数据表
    create table tb
    (
    id int,
    class char(6),
    flg int
    )
    go
    --插入测试数据
    insert into tb select 1,'up1',0
    union all select 1,'down1',1
    union all select 1,'up2',0
    union all select 1,'down2',1
    union all select 2,'up1',0
    union all select 2,'down1',1
    union all select 2,'up2',0
    union all select 3,'up1',0
    union all select 4,'up1',0
    union all select 5,'up1',0
    union all select 5,'down1',1
    union all select 5,'up2',0
    union all select 5,'down2',1
    go
    --代码实现declare @temp table
    (_ID int identity,
    id int,
    class char(6),
    flg int)
    insert into @temp
    select * from tbselect a.id,a.class classUp,case when b.class like 'down%' then b.class else '-' end classDown from @temp a left join @temp b on a._ID=b._ID-1
    where a.class like 'up%'
    /*结果id classUp classDown 
    -----------------------------  
    1 up1 down1   
    1 up2 down2   
    2 up1 down1
    2 up2 -
    3 up1 -
    4 up1 -
    5 up1 down1   
    5 up2 down2*/
      

  9.   


    IF OBJECT_ID('[tb]') IS NOT NULL
        DROP TABLE [tb]
    GO
    CREATE TABLE [tb]([id] INT,[class] NVARCHAR(10),[flg] NVARCHAR(10))
    INSERT [tb]
    SELECT 1,'up1','0' UNION ALL
    SELECT 1,'down1','1' UNION ALL
    SELECT 1,'up2','0' UNION ALL
    SELECT 1,'down2','1' UNION ALL
    SELECT 2,'up1','0' UNION ALL
    SELECT 2,'down1','1' UNION ALL
    SELECT 2,'up2','0' UNION ALL
    SELECT 3,'up1','0' UNION ALL
    SELECT 4,'up1','0' UNION ALL
    SELECT 5,'up1','0' UNION ALL
    SELECT 5,'down1','1' UNION ALL
    SELECT 5,'up2','0' UNION ALL
    SELECT 5,'down2','1'SELECT a.id,a.class,isnull(b.class,'---') FROM
    (SELECT * FROM tb WHERE flg=0)a 
    LEFT JOIN (SELECT * FROM tb WHERE flg=1)b
    ON a.id=b.id AND RIGHT(a.class,1)=RIGHT(b.class,1)
     
      

  10.   

    问题是我这表里class数据不一定是up1,down1,up2,down2的
    可能是a,b,c,d
    是排序了之后把flg的0,1成对的合并,只有0没有1的"-"显示
    不知道大家明白了没有 - -##
      

  11.   

    --sql 2000
    CREATE TABLE [tb]([id] INT,[class] NVARCHAR(10),[flg] NVARCHAR(10))
    INSERT [tb]
    SELECT 1,'up1','0' UNION ALL
    SELECT 1,'down1','1' UNION ALL
    SELECT 1,'up2','0' UNION ALL
    SELECT 1,'down2','1' UNION ALL
    SELECT 2,'up1','0' UNION ALL
    SELECT 2,'down1','1' UNION ALL
    SELECT 2,'up2','0' UNION ALL
    SELECT 3,'up1','0' UNION ALL
    SELECT 4,'up1','0' UNION ALL
    SELECT 5,'up1','0' UNION ALL
    SELECT 5,'down1','1' UNION ALL
    SELECT 5,'up2','0' UNION ALL
    SELECT 5,'down2','1'select m.id , m.class class1,isnull(n.class,'-') class2 from
    (select t.* , px = (select count(1) from tb where flg = '0' and id = t.id and class < t.class) + 1 from tb t where flg = '0') m
    left join
    (select t.* , px = (select count(1) from tb where flg = '1' and id = t.id and class < t.class) + 1 from tb t where flg = '1') n
    on m.id = n.id and m.px = n.pxdrop table tb/*
    id          class1     class2     
    ----------- ---------- ---------- 
    1           up1        down1
    1           up2        down2
    2           up1        down1
    2           up2        -
    3           up1        -
    4           up1        -
    5           up1        down1
    5           up2        down2(所影响的行数为 8 行)
    */--sql 2005
    CREATE TABLE [tb]([id] INT,[class] NVARCHAR(10),[flg] NVARCHAR(10))
    INSERT [tb]
    SELECT 1,'up1','0' UNION ALL
    SELECT 1,'down1','1' UNION ALL
    SELECT 1,'up2','0' UNION ALL
    SELECT 1,'down2','1' UNION ALL
    SELECT 2,'up1','0' UNION ALL
    SELECT 2,'down1','1' UNION ALL
    SELECT 2,'up2','0' UNION ALL
    SELECT 3,'up1','0' UNION ALL
    SELECT 4,'up1','0' UNION ALL
    SELECT 5,'up1','0' UNION ALL
    SELECT 5,'down1','1' UNION ALL
    SELECT 5,'up2','0' UNION ALL
    SELECT 5,'down2','1'select m.id , m.class class1,isnull(n.class,'-') class2 from
    (select t.* , px = row_number() over(partition by id order by class) from tb t where flg = '0') m
    left join
    (select t.* , px = row_number() over(partition by id order by class) from tb t where flg = '1') n
    on m.id = n.id and m.px = n.pxdrop table tb/*
    id          class1     class2
    ----------- ---------- ----------
    1           up1        down1
    1           up2        down2
    2           up1        down1
    2           up2        -
    3           up1        -
    4           up1        -
    5           up1        down1
    5           up2        down2(8 行受影响)*/