#sql #postgresql
Вопрос:
Я пытаюсь найти повторения между строками на основе столбца. Я пробовал оконные функции с row_number() / rank (), но они группируют все найденные значения (аналогично GROUP BY), чего я не ожидаю. Как я могу найти повторения значений?
Я пытался сделать что-то вроде этого:
SELECT *, rank() OVER(PARTITION BY customer ORDER BY id) FROM customers ORDER BY id
И получил следующий результат:
ID | покупатель | ранг |
---|---|---|
1 | пользователь_1 | 1 |
2 | клиент_2 | 1 |
3 | клиент_2 | 2 |
4 | пользователь_1 | 2 |
5 | customer_3 | 1 |
6 | пользователь_1 | 3 |
Что я хочу сделать:
ID | покупатель | ранг |
---|---|---|
1 | пользователь_1 | 1 |
2 | клиент_2 | 1 |
3 | клиент_2 | 2 |
4 | пользователь_1 | 1 |
5 | customer_3 | 1 |
6 | пользователь_1 | 1 |
Ответ №1:
Вы ищете количество в соседних строках. Это своего рода проблема пробелов и островов. Вы можете определить соседние строки с разницей row_numbers()
в, а затем перечислить их:
SELECT c.*,
ROW_NUMBER() OVER (PARTITION BY customer, seqnum - seqnum_2 ORDER BY id) as ranking
FROM (SELECT c.*,
ROW_NUMBER() OVER (ORDER BY id) as seqnum,
ROW_NUMBER() OVER (PARTITION BY customer ORDER BY id) as seqnum_2
FROM customers c
) c
ORDER BY id
Комментарии:
1. Спасибо, это работает. Неужели это действительно должен быть такой сложный запрос? Проблема казалась намного проще, чем она есть 🙂
2. @Jora . . . Это не особенно сложно.
Ответ №2:
Вы можете использовать рекурсивный запрос:
WITH RECURSIVE repeatitions(id, customer, repeat_count) AS (
SELECT id, customer, 1 as repeat_count
FROM customers
UNION ALL
SELECT c.id, c.customer, r.repeat_count 1
FROM customers c, repeatitions r
WHERE c.id = r.id 1 AND c.customer = r.customer
)
SELECT id, customer, repeat_count
FROM repeatitions
ORDER by id
Я создал рабочую скрипку, чтобы продемонстрировать это.