SQL заявление с наличием, мин, макс - PullRequest
1 голос
/ 28 января 2020

У меня есть таблица:

 ID                INTEGER NOT NULL,  -- AUTOMATIC RECORD'S ID
 CUSTOMER_ID       INTEGER NOT NULL,
 BILING_PERIOD     DATE    NOT NULL,
 DOCUMENT_ID       INTEGER NOT NULL,   
 DATE_CREATED      DATE    NOT NULL  -- WHEN THE DOCUMENT WAS CREATED

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

Поэтому, когда у нас есть, например, такие данные:

ID CUSTOMER_ID BILING_PERIOD DOCUMENT_ID DATE_CREATED
1  5           2020-01-01    123         2020-02-01
2  5           2020-01-01    22          2019-02-01
3  5           2020-01-01    3           2010-02-01
4  99          2020-01-01    458         2021-02-01
5  99          2020-01-01    64          2010-02-01
6  100         2020-01-01    120         2020-02-01
7  99          2019-06-01    452         2019-06-01
8  99          2019-06-01    546         2019-12-01

Я хочу, чтобы мои результаты выглядели так:

CUSTOMER_ID BILING_PERIOD NR_OF_DOC FIRST_DOC_ID LAST_DOC_ID
5           2020-01-01    3         3            123
99          2019-06-01    2         452          546
99          2020-01-01    2         64           458

Сам я могу рассчитывать только количество документов на пользователя и период

SELECT customer_id, biling_period, count(*) as nr_of_doc
FROM T1
GROUP BY customer_id, biling_period
HAVING COUNT() > 1;

CUSTOMER_ID BILING_PERIOD NR_OF_DOC 
5           2020-01-01    3         
99          2019-06-01    2         
99          2020-01-01    2 

Я не знаю, как получить document_id для самого нового и самого старого документа.

Ответы [ 2 ]

1 голос
/ 28 января 2020

Вы можете использовать row_number() и агрегацию:

select 
    customer_id,
    billing_period,
    count(*),
    max(case when rn_asc  = 1 then document_id end) fist_doc_id,
    max(case when rn_desc = 1 then document_id end) last_doc_id
from (
    select 
        t.*,
        row_number() over( 
            partition by customer_id, billing_period order by date_created
        ) rn_asc,
        row_number() over( 
            partition by customer_id, billing_period order by date_created desc
        ) rn_desc
    from t1 t
) t
group by customer_id, billing_period
having count(*) > 1
order by customer_id, billing_period

Это будет работать правильно, даже если идентификаторы документов не в последовательности.

Демонстрация в БД Скрипка :

customer_id | billing_period | count | fist_doc_id | last_doc_id
----------: | :------------- | ----: | ----------: | ----------:
          5 | 2020-01-01     |     3 |           3 |         123
         99 | 2019-06-01     |     2 |         452 |         546
         99 | 2020-01-01     |     2 |          64 |         458
0 голосов
/ 28 января 2020

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

SELECT customer_id, billing_period, count(*) as nr_of_doc,
       MIN(document_id), MAX(document_id)
FROM T1
GROUP BY customer_id, billing_period
HAVING COUNT() > 1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...