2015-09-14 3 views
0

Я хочу получить последовательность столбцов типов, имеющих длину больше единицы для разных идентификаторов.Выберите последовательные записи столбцов, а также найдите самую длинную последовательность

таблица создается следующим образом

id | type 
----+------ 
    1 | E1 
    1 | E1 
    2 | A3 
    3 | B2 
    1 | A1 
    4 | C1 
    5 | C 
    7 | D 
    8 | D 
    9 | A1 
    3 | D 
(11 rows) 

Вот что я пытаюсь достичь первого:

id | type 
1 | E1 
1 | E1 
1 | A1 
3 | B2 
3 | D 

Результат выше, что я должен получить с последовательностью типов E1,E1,A1 для идентификатора 1 и B2,D для идентификатора 3.

Я пробовал это, что, несомненно, является ошибочным:

select q1.id, q1.type 
from 
    (select row_number() over() as rowno, * from recs) q1, 
    (select row_number() over() as rowno, * from recs) q2 
where q1.rowno > q2.rowno and q1.id = q2.id;` 

Это дает мне что-то вроде:

id | type 
----+------ 
    1 | E1 
    1 | A1 
    1 | A1 
    3 | D 
(4 rows) 

После этого я хочу найти самую длинную последовательность.

+0

См. Также: [Se наиболее длинная непрерывная последовательность] (http://dba.stackexchange.com/q/35380/3684). Ваш случай - «более простая альтернатива». –

ответ

1

Попробуйте это. CTE получает идентификаторы с более чем одной записью, и запрос извлекает только те записи.

WITH ids_recurring_more_than_once AS 
(SELECT id FROM mytable GROUP BY id HAVING COUNT(*) >1) 
SELECT m.* FROM mytable m 
INNER JOIN ids_recurring_more_than_once 
ON m.id = ids_recurring_more_than_once.id 

С помощью «самой длинной последовательности» вы имеете в виду идентификатор с наибольшим количеством повторений? В этом случае замените КТР с:

SELECT id FROM mytable GROUP BY id ORDER BY COUNT(*) DESC LIMIT 1 
+0

Дольше всего я бы хотел, чтобы последовательность E1, E1, A1 –

+0

В этом случае просто используйте последний запрос в CTE (оператор в скобках после «WITH»). И вместо m. * Вы можете просто использовать m.type. – mlinth

+0

С ids_recurring_more_than_once AS (SELECT идентификатор из РИК GROUP BY идентификатора HAVING COUNT (*)> 1 порядка по количеству (*) предела по убыванию 1) SELECT, м. * ОТ РИК м INNER JOIN ids_recurring_more_than_once ПО m.id = ids_recurring_more_than_once. id ; –

1

Вы можете использовать count() over partition:

select id, typ 
from (
    select *, count(*) over (partition by id) seq_len 
    from recs 
    ) sub 
where seq_len > 1 

id | typ 
----+----- 
    1 | A1 
    1 | E1 
    1 | E1 
    3 | D 
    3 | B2 
(5 rows)  

или агрегировать последовательности:

select * 
from (
    select id, array_agg(typ) seq 
    from recs 
    group by 1 
    ) sub 
where array_length(seq, 1) > 1 

id | seq 
----+------------ 
    1 | {E1,E1,A1} 
    3 | {B2,D} 
(2 rows)  

Используйте последний запрос, чтобы выбрать самую длинную последовательность:

select id, seq, array_length(seq, 1) seq_len 
from (
    select id, array_agg(typ) seq 
    from recs 
    group by 1 
    ) sub 
order by 3 desc 
limit 1 

id | seq  | seq_len 
----+------------+--------- 
    1 | {E1,E1,A1} |  3 
(1 row) 
+0

array_agg отлично звучит. Я буду использовать это. –

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