【问题标题】:kdb+ equivalent of SQL's rank() and dense_rank()kdb+ 相当于 SQL 的 rank() 和 dense_rank()
【发布时间】:2019-04-10 20:13:54
【问题描述】:

任何人都必须在kdb+中模拟SQL的rank()、dense_rank()和row_number()的结果?这里有一些 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)

谢谢!

【问题讨论】:

    标签: kdb


    【解决方案1】:

    如果您最初按课程对表格进行排序并标记:

    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
    

    此解决方案使用rankvirtual index column,如果您想进一步了解这些内容。

    【讨论】:

      【解决方案2】:

      对于按目标列排序的表:

      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
      

      【讨论】:

        【解决方案3】:

        我现在可以想到这个: 注意:kdb 中的 rank 函数适用于 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
        
        course mark name dense_rank rank_rank row_num
        Maths 60 Thulile 2 2 1
        Maths 60 Pritha 2 2 2
        Maths 70 Voitto 1 1 3
        Maths 55 Chun 3 4 4
        Biology 60 Bilal 2 2 1
        Biology 70 Roger 1 1 2

        【讨论】:

          猜你喜欢
          • 2022-01-14
          • 1970-01-01
          • 2012-06-26
          • 2019-11-14
          • 2022-01-04
          • 1970-01-01
          • 2021-09-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多