Извлечение следующих 3 или смежных строк на основе условия в postgreSQL - PullRequest
0 голосов
/ 28 августа 2018

У меня есть база данных более 10000 строк. например:

id text 
1  abc
2  ghj
3  cde
4  hif
5  klm
6  bbc
7  jkl
8  mno
9  dbo
10 ijk

Мне нужно получить следующие три строки, где текст соответствует условию.

Например: если я выполняю текст, подобный запросу '% bc%, он должен вернуть мне строки с идентификаторами 1,2,3,4,6,7,8,9, поскольку строка № 1 и № 6 совпадают

Ответы [ 4 ]

0 голосов
/ 28 августа 2018

Я не собираюсь предполагать, что у id нет пробелов. Один метод использует lag():

select t.*
from (select t.*,
             lag(text) over (order by id) as prev_text,
             lag(text, 2) over (order by id) as prev_text2,
             lag(text, 3) over (order by id) as prev_text3
      from t
     ) t
where text like '%bc%' or
      prev_text like '%bc%' or
      prev_text2 like '%bc%' or
      prev_text3 like '%bc%';

Вы также можете сделать это с одним сравнением, используя другие функции окна:

select id, text
from (select t.*,
             sum( (text like '%bc%')::int ) over (order by id rows between 3 preceding and current row) as cnt
      from t
     ) t
where cnt > 0;

С индексом id это может быть самый быстрый подход к решению проблемы.

0 голосов
/ 28 августа 2018
with -- Test data
  t(i, x) as (values
    (1,'abc'),(2,'ghj'),(3,'cde'),(4,'hif'),(5,'klm'),(6,'bbc'),(7,'jkl'),(8,'mno'),(9,'dbo'),(10,'ijk'))
select r.*
from
  t as t0 cross join lateral (
    select *
    from t
    where t.i >= t0.i
    order by t.i
    limit 4) as r
where t0.x like '%bc%'
order by r.i;

Боковые объединения позволяет использовать предыдущую таблицу в следующем подзапросе.

0 голосов
/ 28 августа 2018

Вы можете использовать что-то вроде этого:

SELECT next.*
FROM test, test next
WHERE test.text LIKE '%bc%'
  AND (test.id + 1 = next.id OR test.id + 2 = next.id OR test.id + 3 = next.id)
0 голосов
/ 28 августа 2018

Используйте запрос ниже, чтобы получить желаемый результат. Я предполагаю, что вы хотите рассчитать следующий, основываясь только на ID, а ID всегда увеличивается на 1, как вы упоминали в вопросе.

Если идентификатор не всегда увеличивается на 1, то сначала добавьте номер строки, а затем замените идентификатор в подзапросе t2 и объедините условие с номером строки.

select t1.id, t1.id_text 
from test t1
join
(
select id from test where id_text like '%bc%'
UNION
select id+1 from test where id_text like '%bc%'
UNION
select id+2 from test where id_text like '%bc%'
UNION
select id+3 from test where id_text like '%bc%'
) t2
on t1.id = t2.id;

Ссылка SQL Fiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...