2014-12-12 3 views
1

Привет всем У меня есть следующий КТР ... то, что я пытаюсь сделать, это иметь идентификатор и затем каскадный список СтатусTeradata Рекурсивный CTE Соединить Ряды

так, например ... если у меня есть

1, 1234, Hot 
2, 1234, Cold 
3, 1234, Warm 

Я хочу, чтобы в конечном итоге с

1234,'Hot,Cold,Warm' 

Мой КТР

with recursive temp_table(RowNumber, Id, Status) as ( 
select 
    row_number() over (order by OBJECT_STATUS) as RowNumber 
    ,OBJECT_ID 
    ,cast(OBJECT_STATUS as varchar(100)) as Status 
from 
    CORE_ORDER_STATUS 
where 
    OBJECT_ID = 'OR000008387722' 
union all 
select 
    a.RowNumber + 1 as NextOne 
    ,b.OBJECT_ID 
    ,a.Status || ',' || cast(b.OBJECT_STATUS as varchar(5)) as Status 
from 
    CORE_ORDER_STATUS b 
inner join 
    temp_table a 
on 
    a.Id = b.OBJECT_ID 
where 
    a.RowNumber = b.NextOne 
) 
select * from temp_table; 
+0

является SQL Server RDBMS за этим? Похоже, что так. –

+1

Каков ваш реальный вопрос? – Andrew

+0

Спасибо, Андрей, вопреки распространенному мнению ... Английский - это мой первый язык. Я установил вопрос – jim

ответ

1

Предполагая, что интерпретация Робы Паллера о вашей проблеме правильно (и я думаю, что это), вот как бы я справиться с этим, с некоторыми запутаны изменчивыми временными таблицами для исходных данных:

create volatile table vt_test as (
select 
'1234' as object_id, 
cast ('Hot' as varchar(1000)) as object_status 

) with data 
primary index (object_id) 
on commit preserve rows; 

insert into vt_test values ('1234','Cold'); 
insert into vt_test values ('1234','Warm'); 
insert into vt_test values ('5678','Red'); 
insert into vt_test values ('5678','Blue'); 
insert into vt_test values ('5678','Green'); 


create volatile table vt_two as(
select 
row_number() over (partition by object_id order by object_status) as RN, 
object_id, 
object_status 
from 
vt_test) with data 
primary index (object_id) 
on commit preserve rows; 


with RECURSIVE CTE (RN,Object_id,Object_Status,counter) as (
SELECT 
RN, 
object_id, 
Object_Status, 
cast(1 as integer) 
from 
vt_two 
where RN = 1 
UNION ALL 
select 
b.rn, 
b.object_id, 
a.object_status || ',' || b.object_status as Object_Status, 
counter + 1 
from 
vt_two a 
inner join cte b 
on a.object_id = b.object_id 
and a.rn = b.counter + 1 
) 

select 
* 
from 
CTE 
qualify rank() over (partition by object_id order by counter desc) = 1; 

который даст вы:

1 1234 Warm,Hot,Cold 3 
1 5678 Red,Green,Blue 3 

Предложение qualify в конце концов, является ключевым здесь. Прокомментируйте это, и это довольно ясно, что он делает.

Вы должны быть очень осторожны с рекурсивными CTE, по крайней мере, в Teradata. Очень легко написать запрос, который в принципе никогда не закончится.

+0

Вы можете добавить квалификацию в свой CTE, чтобы установить ограничение на глубину рекурсии. Обычно в колонке 'counter'. –

1

Ваш SELECT из CTE возвращает каждую строку. Вам нужна запись с самым высоким RowNumber, который, как мне кажется, потребует HAVING RowNumber=MAX(RowNumber), включенного вместе с предложением GROUP BY для возвращаемых столбцов.

Смежные вопросы