Выделение и объединение строк в таблице в хранимой процедуре SQL - PullRequest
0 голосов
/ 24 октября 2009

Есть временная таблица со схемой: ID | SeqNo | Имя

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 ]

3 голосов
/ 24 октября 2009

Если 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;
3 голосов
/ 24 октября 2009

Если вы знаете, 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: другая версия, основанная на примере рекурсии Ремуса. Я не мог придумать, как выбрать только последнюю рекурсию для идентификатора без агрегирования или сортировки. Кто-нибудь знает?

;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;
0 голосов
/ 15 ноября 2010

Решение хорошее. У меня похожая проблема, но здесь я использую 2 разных таблицы. например:

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 | 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...