kdb + эквивалент ранга SQL () и dens_rank () - PullRequest
1 голос
/ 10 апреля 2019

Любой из них должен имитировать результат SQL rank (), dens_rank () и row_number () в kdb +?Вот несколько SQL для демонстрации возможностей.Если у кого-то есть конкретное решение ниже, возможно, я мог бы поработать над его обобщением для поддержки нескольких разделов и упорядочения по столбцам - и опубликовать сообщение на этом сайте.

CREATE TABLE student(course VARCHAR(10), mark int, name varchar(10));

INSERT INTO student VALUES  
('Maths', 60, 'Thulile'),
('Maths', 60, 'Pritha'),
('Maths', 70, 'Voitto'),
('Maths', 55, 'Chun'),
('Biology', 60, 'Bilal'),
('Biology', 70, 'Roger');

SELECT
 RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS rank,
 DENSE_RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS dense_rank,
 ROW_NUMBER() OVER (PARTITION BY course ORDER BY mark DESC) AS row_num,
 course, mark, name 
FROM student ORDER BY course, mark DESC;

+------+------------+---------+---------+------+---------+
| rank | dense_rank | row_num | course  | mark | name    |
+------+------------+---------+---------+------+---------+
|    1 |          1 |       1 | Biology |   70 | Roger   |
|    2 |          2 |       2 | Biology |   60 | Bilal   |
|    1 |          1 |       1 | Maths   |   70 | Voitto  |
|    2 |          2 |       2 | Maths   |   60 | Thulile |
|    2 |          2 |       3 | Maths   |   60 | Pritha  |
|    4 |          3 |       4 | Maths   |   55 | Chun    |
+------+------------+---------+---------+------+---------+

Вот некоторые kdb + для генерации эквивалентного студентаТаблица:

student:([] course:`Maths`Maths`Maths`Maths`Biology`Biology; 
   mark:60 60 70 55 60 70; 
   name:`Thulile`Pritha`Voitto`Chun`Bilal`Roger)

Спасибо!

Ответы [ 3 ]

3 голосов
/ 11 апреля 2019

Если вы сначала отсортировали таблицу по курсу и отметили:

student:`course xasc `mark xdesc ([] course:`Maths`Maths`Maths`Maths`Biology`Biology;mark:60 60 70 55 60 70;name:`Thulile`Pritha`Voitto`Chun`Bilal`Roger)
course  mark name
--------------------
Biology 70   Roger
Biology 60   Bilal
Maths   70   Voitto
Maths   60   Thulile
Maths   60   Pritha
Maths   55   Chun

Тогда вы можете использовать что-то подобное ниже для достижения вашего результата:

update rank_sql:first row_num by course,mark from update dense_rank:1+where count each (where differ mark)cut mark,row_num:1+rank i by course from  student

course  mark name    dense_rank row_num rank_sql
------------------------------------------------
Biology 70   Roger   1          1       1
Biology 60   Bilal   2          2       2
Maths   70   Voitto  1          1       1
Maths   60   Thulile 2          2       2
Maths   60   Pritha  2          3       2
Maths   55   Chun    3          4       4

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

1 голос
/ 20 апреля 2019

Я могу думать об этом сейчас: Примечание: функция rank в kdb работает со списком asc, поэтому я создал следующие функции. Я не буду xdesc таблицы, так как я могу просто использовать векторную колонку и описать ее

q)denseF
{((desc distinct x)?x)+1}
q)rankF
{((desc x)?x)+1}

q)update dense_rank:denseF mark,rank_rank:rankF mark,row_num:1+rank i by course from student

название отметки курса Математика 60 Thulile 2 2 1
Математика 60 Прита 2 2 2
Математика 70 Войтто 1 1 3
Математика 55 Чунь 3 4 4
Биология 60 Билал 2 2 1
Биология 70 Роджер 1 1 2

1 голос
/ 11 апреля 2019

Для таблицы, упорядоченной по целевым столбцам:

q) dense_sql:{sums differ x}
q) rank_sql:{raze #'[(1_deltas b),1;b:1+where differ x]}
q) row_sql:{1+til count x}

q) student:`course xasc `mark xdesc ([] course:`Maths`Maths`Maths`Maths`Biology`Biology;mark:60 60 70 55 60 70;name:`Thulile`Pritha`Voitto`Chun`Bilal`Roger)

q)update row_num:row_sql mark,rank_s:rank_sql mark,dense_s:dense_sql mark by course from student
...