mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Implemented cume_dist function.
Also fixed a bug in row_counts detection, when partition changes.
This commit is contained in:
62
mysql-test/r/win_percent_cume.result
Normal file
62
mysql-test/r/win_percent_cume.result
Normal file
@ -0,0 +1,62 @@
|
||||
create table t1 (
|
||||
pk int primary key,
|
||||
a int,
|
||||
b int
|
||||
);
|
||||
insert into t1 values
|
||||
( 1 , 0, 10),
|
||||
( 2 , 0, 10),
|
||||
( 3 , 1, 10),
|
||||
( 4 , 1, 10),
|
||||
( 8 , 2, 10),
|
||||
( 5 , 2, 20),
|
||||
( 6 , 2, 20),
|
||||
( 7 , 2, 20),
|
||||
( 9 , 4, 20),
|
||||
(10 , 4, 20);
|
||||
select pk, a, b,
|
||||
percent_rank() over (order by a),
|
||||
cume_dist() over (order by a)
|
||||
from t1;
|
||||
pk a b percent_rank() over (order by a) cume_dist() over (order by a)
|
||||
1 0 10 0.0000000000 0.2000000000
|
||||
2 0 10 0.0000000000 0.2000000000
|
||||
3 1 10 0.2222222222 0.4000000000
|
||||
4 1 10 0.2222222222 0.4000000000
|
||||
8 2 10 0.4444444444 0.8000000000
|
||||
5 2 20 0.4444444444 0.8000000000
|
||||
6 2 20 0.4444444444 0.8000000000
|
||||
7 2 20 0.4444444444 0.8000000000
|
||||
9 4 20 0.8888888889 1.0000000000
|
||||
10 4 20 0.8888888889 1.0000000000
|
||||
select pk, a, b,
|
||||
percent_rank() over (order by pk),
|
||||
cume_dist() over (order by pk)
|
||||
from t1 order by pk;
|
||||
pk a b percent_rank() over (order by pk) cume_dist() over (order by pk)
|
||||
1 0 10 0.0000000000 0.1000000000
|
||||
2 0 10 0.1111111111 0.2000000000
|
||||
3 1 10 0.2222222222 0.3000000000
|
||||
4 1 10 0.3333333333 0.4000000000
|
||||
5 2 20 0.4444444444 0.5000000000
|
||||
6 2 20 0.5555555556 0.6000000000
|
||||
7 2 20 0.6666666667 0.7000000000
|
||||
8 2 10 0.7777777778 0.8000000000
|
||||
9 4 20 0.8888888889 0.9000000000
|
||||
10 4 20 1.0000000000 1.0000000000
|
||||
select pk, a, b,
|
||||
percent_rank() over (partition by a order by a),
|
||||
cume_dist() over (partition by a order by a)
|
||||
from t1;
|
||||
pk a b percent_rank() over (partition by a order by a) cume_dist() over (partition by a order by a)
|
||||
1 0 10 0.0000000000 1.0000000000
|
||||
2 0 10 0.0000000000 1.0000000000
|
||||
3 1 10 0.0000000000 1.0000000000
|
||||
4 1 10 0.0000000000 1.0000000000
|
||||
8 2 10 0.0000000000 1.0000000000
|
||||
5 2 20 0.0000000000 1.0000000000
|
||||
6 2 20 0.0000000000 1.0000000000
|
||||
7 2 20 0.0000000000 1.0000000000
|
||||
9 4 20 0.0000000000 1.0000000000
|
||||
10 4 20 0.0000000000 1.0000000000
|
||||
drop table t1;
|
36
mysql-test/t/win_percent_cume.test
Normal file
36
mysql-test/t/win_percent_cume.test
Normal file
@ -0,0 +1,36 @@
|
||||
create table t1 (
|
||||
pk int primary key,
|
||||
a int,
|
||||
b int
|
||||
);
|
||||
|
||||
|
||||
insert into t1 values
|
||||
( 1 , 0, 10),
|
||||
( 2 , 0, 10),
|
||||
( 3 , 1, 10),
|
||||
( 4 , 1, 10),
|
||||
( 8 , 2, 10),
|
||||
( 5 , 2, 20),
|
||||
( 6 , 2, 20),
|
||||
( 7 , 2, 20),
|
||||
( 9 , 4, 20),
|
||||
(10 , 4, 20);
|
||||
|
||||
select pk, a, b,
|
||||
percent_rank() over (order by a),
|
||||
cume_dist() over (order by a)
|
||||
from t1;
|
||||
|
||||
select pk, a, b,
|
||||
percent_rank() over (order by pk),
|
||||
cume_dist() over (order by pk)
|
||||
from t1 order by pk;
|
||||
|
||||
select pk, a, b,
|
||||
percent_rank() over (partition by a order by a),
|
||||
cume_dist() over (partition by a order by a)
|
||||
from t1;
|
||||
|
||||
drop table t1;
|
||||
|
@ -422,27 +422,62 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count
|
||||
window ordering of the window partition of R
|
||||
- NR is defined to be the number of rows in the window partition of R.
|
||||
|
||||
Just like with Item_sum_percent_rank, compuation of this function requires
|
||||
Just like with Item_sum_percent_rank, computation of this function requires
|
||||
two passes.
|
||||
*/
|
||||
|
||||
class Item_sum_cume_dist: public Item_sum_percent_rank
|
||||
class Item_sum_cume_dist: public Item_sum_window_with_row_count
|
||||
{
|
||||
public:
|
||||
Item_sum_cume_dist(THD *thd)
|
||||
: Item_sum_percent_rank(thd) {}
|
||||
Item_sum_cume_dist(THD *thd) : Item_sum_window_with_row_count(thd),
|
||||
current_row_count_(0) {}
|
||||
|
||||
double val_real() { return 0; }
|
||||
double val_real()
|
||||
{
|
||||
if (get_row_count() == 0)
|
||||
{
|
||||
null_value= true;
|
||||
return 0;
|
||||
}
|
||||
ulonglong partition_row_count= get_row_count();
|
||||
null_value= false;
|
||||
return static_cast<double>(current_row_count_) / partition_row_count;
|
||||
}
|
||||
|
||||
bool add()
|
||||
{
|
||||
current_row_count_++;
|
||||
return false;
|
||||
}
|
||||
|
||||
enum Sumfunctype sum_func () const
|
||||
{
|
||||
return CUME_DIST_FUNC;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
current_row_count_= 0;
|
||||
set_row_count(0);
|
||||
}
|
||||
|
||||
const char*func_name() const
|
||||
{
|
||||
return "cume_dist";
|
||||
}
|
||||
|
||||
void update_field() {}
|
||||
enum Item_result result_type () const { return REAL_RESULT; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
|
||||
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
decimals = 10; // TODO-cvicentiu find out how many decimals the standard
|
||||
// requires.
|
||||
}
|
||||
|
||||
private:
|
||||
ulonglong current_row_count_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -923,8 +923,8 @@ class Frame_unbounded_following_set_count : public Frame_unbounded_following
|
||||
/* Read the first row */
|
||||
if (cursor.get_next())
|
||||
return;
|
||||
num_rows_in_partition++;
|
||||
}
|
||||
num_rows_in_partition++;
|
||||
|
||||
/* Remember which partition we are in */
|
||||
bound_tracker.check_if_next_group();
|
||||
@ -1412,8 +1412,6 @@ bool compute_window_func_with_frames(Item_window_func *item_win,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Make a list that is a concation of two lists of ORDER elements */
|
||||
|
||||
static ORDER* concat_order_lists(MEM_ROOT *mem_root, ORDER *list1, ORDER *list2)
|
||||
|
Reference in New Issue
Block a user