代码之家  ›  专栏  ›  技术社区  ›  lakshminb7

在SQL存储过程中选择并合并表中的行

  •  0
  • lakshminb7  · 技术社区  · 16 年前

    具有架构为:id seqno name的临时表

    ID-不唯一
    seqno-int(可以是1、2或3)。将id+seqno排序为主键
    姓名-任何文本

    表中的示例数据如下

    1 | 1 | RecordA  
    2 | 1 | RecordB  
    3 | 1 | RecordC  
    1 | 2 | RecordD  
    4 | 1 | RecordE  
    5 | 1 | RecordF  
    3 | 1 | RecordG  
    

    需要从此表中选择并输出

    1 | RecordA/RecordD  
    2 | RecordB  
    3 | RecordC/RecordG  
    4 | RecordE  
    5 | RecordF  
    

    需要在没有光标的情况下执行此操作。

    3 回复  |  直到 13 年前
        1
  •  3
  •   Andomar    16 年前

    如果SEQNO限于1、2、3:

    select id, a.name + coalesce('/'+b.name, '') + coalesce('/'+c.name, '')
    from myTable a
    left outer join myTable b on a.id=b.id and b.seqno = 2
    left outer join myTable c on a.id=c.id and c.seqno = 3
    where a.seqno = 1;
    

    如果seqno是开放式的,则可以部署递归CTE:

    ;with anchor as (
       select id, name, seqno
          from myTable
          where seqno=1)
    , recursive as (
       select id, name, seqno
          from anchor
          union all
       select t.id, r.name + '/' + t.name, t.seqno
          from myTable t
          join recursive  r on t.id = r.id and r.seqno+1 = t.seqno)
    select id, name from recursive;
    
        2
  •  3
  •   Peter Radocchia    16 年前

    如果你知道Seqno永远不会超过3个:

    select Id, Names = stuff(
        max(case when SeqNo = 1 then '/'+Name else '' end)
      + max(case when SeqNo = 2 then '/'+Name else '' end)
      + max(case when SeqNo = 3 then '/'+Name else '' end)
      , 1, 1, '')
    from table1 
    group by Id
    

    否则,类似这样的问题是任意数量项目的通用解决方案:

    select Id, Names = stuff((
      select '/'+Name from table1 b
      where a.Id = b.Id order by SeqNo
      for xml path (''))
      , 1, 1, '')
    from table1 a
    group by Id
    

    或者写一个clr uda。

    编辑:相关表上的别名错误!

    edit2:另一个版本,基于remus的递归示例。我想不出任何方法来选择 只有 每个ID的最后一个递归,不进行聚合或排序。有人知道吗?

    ;with
      myTable as (
        select * from (
          values 
            (1, 1, 'RecordA')  
          , (2, 1, 'RecordB')  
          , (3, 1, 'RecordC')  
          , (1, 2, 'RecordD')  
          , (4, 1, 'RecordE')  
          , (5, 1, 'RecordF')  
          , (3, 2, 'RecordG')
          ) a (Id, SeqNo, Name)
        )    
    , anchor as (
        select id, name = convert(varchar(max),name), seqno
        from myTable where seqno=1
        )
    , recursive as (
        select id, name, seqno
        from anchor
        union all
        select t.id, r.name + '/' + t.name, t.seqno
        from myTable t
        join recursive  r on t.id = r.id and r.seqno+1 = t.seqno
        )
    select id, name = max(name) 
    from recursive
    group by id;
    ---- without aggregation, we get 7 rows:
    --select id, name
    --from recursive;
    
        3
  •  0
  •   j0k gauthamp    13 年前

    解决方案是好的。我有一个类似的问题,但这里我使用了两个不同的表。前任:

    table1 
    
    1 | 1 |
    2 | 3 |
    3 | 1 |
    4 | 2 |
    5 | 1 |
    1 | 2 |
    1 | 3 | 
    4 | 1 |
    5 | 2 |
    2 | 2 |
    4 | 3 |
    
    table2 
    1 | RecordA
    2 | RecordB
    3 | RecordC
    

    我想从两个表中获取数据并以下面的格式显示。

    1 | RecordA,RecordB,RecordC|
    2 | RecordB,RecordC|
    3 | RecordA |
    4 | RecordA,RecordB,RecordC|
    5 | RecordA,RecordB |