postgresql
Функции окна
Поиск…
общий пример
Подготовка данных:
create table wf_example(i int, t text,ts timestamptz,b boolean);
insert into wf_example select 1,'a','1970.01.01',true;
insert into wf_example select 1,'a','1970.01.01',false;
insert into wf_example select 1,'b','1970.01.01',false;
insert into wf_example select 2,'b','1970.01.01',false;
insert into wf_example select 3,'b','1970.01.01',false;
insert into wf_example select 4,'b','1970.02.01',false;
insert into wf_example select 5,'b','1970.03.01',false;
insert into wf_example select 2,'c','1970.03.01',true;
Бег:
select *
, dense_rank() over (order by i) dist_by_i
, lag(t) over () prev_t
, nth_value(i, 6) over () nth
, count(true) over (partition by i) num_by_i
, count(true) over () num_all
, ntile(3) over() ntile
from wf_example
;
Результат:
i | t | ts | b | dist_by_i | prev_t | nth | num_by_i | num_all | ntile
---+---+------------------------+---+-----------+--------+-----+----------+---------+-------
1 | a | 1970-01-01 00:00:00+01 | f | 1 | | 3 | 3 | 8 | 1
1 | a | 1970-01-01 00:00:00+01 | t | 1 | a | 3 | 3 | 8 | 1
1 | b | 1970-01-01 00:00:00+01 | f | 1 | a | 3 | 3 | 8 | 1
2 | c | 1970-03-01 00:00:00+01 | t | 2 | b | 3 | 2 | 8 | 2
2 | b | 1970-01-01 00:00:00+01 | f | 2 | c | 3 | 2 | 8 | 2
3 | b | 1970-01-01 00:00:00+01 | f | 3 | b | 3 | 1 | 8 | 2
4 | b | 1970-02-01 00:00:00+01 | f | 4 | b | 3 | 1 | 8 | 3
5 | b | 1970-03-01 00:00:00+01 | f | 5 | b | 3 | 1 | 8 | 3
(8 rows)
Объяснение:
dist_by_i : dense_rank() over (order by i)
- это как row_number для разных значений. Может использоваться для количества различных значений i ( count(DISTINCT i)
wold не работает). Просто используйте максимальное значение.
prev_t : lag(t) over ()
- это предыдущее значение t во всем окне. помните, что для первой строки она равна нулю.
nth : nth_value(i, 6) over ()
- значение столбца i шестой строки во всем окне
num_by_i : count(true) over (partition by i)
- количество строк для каждого значения i
num_all : count(true) over ()
- количество строк по всему окну
ntile : ntile(3) over()
разбивает все окно на 3 (насколько это возможно), равное по количеству частей
значения столбцов vs dense_rank vs rank vs row_number
здесь вы можете найти функции.
С помощью таблицы wf_example, созданной в предыдущем примере, запустите:
select i
, dense_rank() over (order by i)
, row_number() over ()
, rank() over (order by i)
from wf_example
Результат:
i | dense_rank | row_number | rank
---+------------+------------+------
1 | 1 | 1 | 1
1 | 1 | 2 | 1
1 | 1 | 3 | 1
2 | 2 | 4 | 4
2 | 2 | 5 | 4
3 | 3 | 6 | 6
4 | 4 | 7 | 7
5 | 5 | 8 | 8
dense_rank заказывает VALUES i по внешнему виду в окне.
i=1
, поэтому первая строка имеет плотность, то следующее и третье значение i не изменяется, поэтому отображается значениеdense_rank
1 - значение FIRST не изменяется. четвертая строкаi=2
, это второе значение i встречается, поэтомуdense_rank
показывает 2, а также для следующей строки. Затем он соответствует значениюi=3
в 6-й строке, поэтому он показывает 3. То же самое для остальных двух значений i . Таким образом, последнее значениеdense_rank
- это количество различных значений i .row_number заказывает ROWS, как они перечислены.
rank Чтобы не путать с
dense_rank
эта функция заказывает значение ROW NUMBER из i . Таким образом, он начинается с трех, но имеет следующее значение 4, что означает, чтоi=2
(новое значение) встречается в строке 4. Тот жеi=3
был встречен в строке 6. Etc ..