prize distribution on the basis of rank using mysql - mysql

I have two tables one is prize table and one is result table
PRIZE TABLE
pm_id pm_fromrank pm_torank pm_prize pool_id
1 1 1 1000 72
2 2 5 500 72
3 6 10 270 72
RESULT TABLE have 3 type of ranks case
1st CASE
rs_id rs_userid rs_rank rs_poolid
1 131 1 72
2 132 1 72
3 133 2 72
4 134 3 72
5 135 4 72
6 136 5 72
7 137 6 72
8 138 6 72
9 139 7 72
10 140 8 72
11 141 9 72
12 142 10 72
2ND CASE
rs_id rs_userid rs_rank rs_poolid
1 131 1 72
2 132 2 72
3 133 3 72
4 134 4 72
5 135 5 72
6 136 6 72
7 137 7 72
8 138 8 72
9 139 9 72
10 140 10 72
11 141 11 72
12 142 12 72
3RD CASE
rs_id rs_userid rs_rank rs_poolid
1 131 1 72
2 132 2 72
3 133 3 72
4 134 4 72
5 135 5 72
6 136 6 72
7 137 7 72
8 138 8 72
9 139 9 72
10 140 10 72
11 141 10 72
12 142 10 72
now i have to distribute price only first 10 user in ascending order in following ways
1ST CASE PRIZE DISTRIBUTION
rs_id rs_userid rs_rank rs_poolid pricemoney
1 131 1 72 750
2 132 1 72 750
3 133 2 72 500
4 134 3 72 500
5 135 4 72 500
6 136 5 72 270
7 137 6 72 270
8 138 6 72 270
9 139 7 72 270
10 140 8 72 270
11 141 9 72 0
12 142 10 72 0
2ND CASE PRIZE DISTRIBUTION
rs_id rs_userid rs_rank rs_poolid pricemoney
1 131 1 72 1000
2 132 2 72 500
3 133 3 72 500
4 134 4 72 500
5 135 5 72 500
6 136 6 72 270
7 137 7 72 270
8 138 8 72 270
9 139 9 72 270
10 140 10 72 270
11 141 11 72 0
12 142 12 72 0
3RD CASE PRIZE DISTRIBUTION
rs_id rs_userid rs_rank rs_poolid pricemoney
1 131 1 72 1000
2 132 2 72 500
3 133 3 72 500
4 134 4 72 500
5 135 5 72 500
6 136 6 72 270
7 137 7 72 270
8 138 8 72 270
9 139 9 72 270
10 140 10 72 90
11 141 10 72 90
12 142 10 72 90
NOTE:- THE PRIZE TABLE AND RESULT TABLE HAVE RELATIONSHIP WITH POOL_ID
I have to find the prize distribution on the basis of rank using mysql and codeignitor

The solution for MySQL version 8+:
WITH
cte1 AS (SELECT *,
ROW_NUMBER() OVER (ORDER BY rs_rank, rs_id) rn,
DENSE_RANK() OVER (ORDER BY rs_rank) drnk
FROM result
ORDER BY rs_rank, rs_id LIMIT 10),
cte2 AS (SELECT cte1.drnk, SUM(prize.pm_prize) totalmoney
FROM cte1
JOIN prize ON cte1.rn BETWEEN prize.pm_fromrank AND pm_torank
GROUP BY cte1.drnk),
cte3 AS (SELECT *,
DENSE_RANK() OVER (ORDER BY rs_rank) drnk
FROM result
ORDER BY rs_rank, rs_id),
cte4 AS (SELECT MAX(drnk) max_drnk
FROM cte1),
cte5 AS (SELECT rs_id, rs_rank, COUNT(*) OVER (PARTITION BY rs_rank) rank_count
FROM cte3
JOIN cte4 ON cte3.drnk <= cte4.max_drnk)
SELECT result.*, cte2.totalmoney / cte5.rank_count pricemoney
FROM cte5
JOIN result USING (rs_id)
JOIN cte2 ON result.rs_rank = cte2.drnk
fiddle with explanations.

Related

MySql sort query with multiple fields

I have two tables "activity_stats" & "activity_stats_values"
activity_stats table
# id, activity_id, kyf_id, kyf_sort
618 84 5 1
619 84 6 2
638 84 4 3
activity_stats_values table
# id, activity_id, player_id, kyf_id, value
2563 84 46 5 45
2564 84 46 6 60
2587 84 47 5 10
2588 84 47 6 25
2589 84 49 5 10
2590 84 49 6 40
2591 84 48 5 30
2592 84 48 6 15
2594 84 46 4 NULL
2595 84 47 4 80
2596 84 48 4 NULL
2597 84 49 4 NULL
Requirement
players should be sorted by values in descending order. Meaning the player with highest value of first keyfigure(kyf_id , kyf_id position based on field "kyf_sort" of table "activity_stats") should be on top (then second key figure, then third key figure).
Expected output
# id, activity_id, player_id, kyf_id, value kyf_sort
2563 84 46 5 45 1
2564 84 46 6 60 2
2594 84 46 4 NULL 3
2591 84 48 5 30 1
2592 84 48 6 15 2
2596 84 48 4 NULL 3
2589 84 49 5 10 1
2590 84 49 6 40 2
2597 84 49 4 NULL 3
2587 84 47 5 10 1
2588 84 47 6 25 2
2595 84 47 4 80 3
OR playes ids in order [46,48,49,47]
I tried the following query
SELECT ac_st_v.activity_id,ac_st_v.player_id,ac_st_v.value,ac_st.kyf_id,ac_st.kyf_sort,pl.first_name ,
(select max(value)
from activity_stats_values
where activity_id=ac_st_v.activity_id
and kyf_id=ac_st.kyf_id
group by activity_id) as m_value
FROM teamplayer.activity_stats_values as ac_st_v
JOIN teamplayer.activity_stats as ac_st
ON ac_st_v.activity_id=ac_st.activity_id
AND ac_st_v.kyf_id=ac_st.kyf_id
JOIN teamplayer.players as pl
ON ac_st_v.player_id=pl.id
where ac_st_v.activity_id= 84
order by ac_st_v.player_id,ac_st.kyf_sort,m_value
Is there any way to sort the values like this?

MYSQL filter our same rows that are next to each other

I have this table, similar to the one below.
Table show player points:
s main player points
d sub main points;
date when it is calculated.
I want to be able to filter rows that are same as s and d staying next to each other. Date should be as the last last one that are the same.
For example, here we should skip ri - 13 as it is the same as ri -12. Also skip ri - 15,19,20,21,22,23 and so on. But rows 28, 29,30,31 should not be skipped and grouped.
I'm asking because GROUP BY for my case do not work. Any ideas?
Table example:
ri date s d
1 2016-05-23 4 355
2 2016-05-16 4 352
3 2016-05-09 4 349
4 2016-05-02 4 352
5 2016-04-25 4 358
6 2016-04-18 4 359
7 2016-04-11 4 200
8 2016-04-04 4 201
9 2016-03-21 4 198
10 2016-03-07 4 199
11 2016-02-29 4 201
12 2016-02-22 4 203
13 2016-02-15 4 203
14 2016-02-08 4 200
15 2016-02-01 4 200
16 2016-01-18 4 201
17 2016-01-11 4 198
18 2016-01-04 4 183
19 2015-12-28 4 183
20 2015-12-21 4 183
21 2015-12-14 4 183
22 2015-12-07 4 183
23 2015-11-30 4 183
24 2015-11-23 4 182
25 2015-11-16 4 149
26 2015-11-09 4 148
27 2015-11-02 4 145
28 2015-10-26 4 109
29 2015-10-19 4 110
30 2015-10-12 4 109
31 2015-10-05 4 110
32 2015-09-28 4 106
33 2015-09-21 4 108
34 2015-09-14 4 109
35 2015-08-31 5 108
36 2015-08-24 5 108
37 2015-08-17 5 136
38 2015-08-10 5 136
39 2015-08-03 4 123
40 2015-07-27 4 122
41 2015-07-20 4 125
42 2015-07-13 4 126
43 2015-06-29 4 130
44 2015-06-22 4 128
45 2015-06-15 4 126
46 2015-06-08 4 120
47 2015-05-25 9 120
48 2015-05-18 9 122
49 2015-05-11 9 121
50 2015-05-04 9 119
51 2015-04-27 9 122
52 2015-04-20 10 124
53 2015-04-13 9 173
54 2015-04-06 9 172
55 2015-03-23 8 174
56 2015-03-09 7 89
57 2015-03-02 7 89
58 2015-02-23 7 92
59 2015-02-16 7 96
60 2015-02-09 8 93
61 2015-02-02 9 88
62 2015-01-19 4 89
63 2015-01-12 4 89
64 2015-01-05 4 94
Coulb be you need a join ..
select a.*, b.*
from my_table as a
inner join my_table as b on a.ri != b.ri
where (a.d - b.d) = 0;
This can be done using not exists. This would select the first of many rows which have the same s and d.
select *
from tablename t1
where not exists (select 1 from tablename t2
where t1.ri = t2.ri+1 and t1.s = t2.s and t1.d = t2.d)

Percentage by Row Group

I have a matrix with rows grouped by Dept (Department). I am trying to get the actual hours / required hours percentage in a column for each row group, but I can only get the total %, not the % by group. Ex:
I should get this:
Total Employee Req Hrs Rep Hrs % Billable hrs % NonBill Hrs % Time Off %
Dept A Total 672 680 101 575 85 140 21 8 1
Emp1 168 170 101 150 89 50 29 0 0
Emp2 168 165 98 120 71 20 12 8 4
Emp3 168 175 104 155 92 20 12 0 0
Emp4 168 170 101 150 89 50 29 0 0
Dept B Total 420 428 102 365 87 80 19 4 .1
Emp5 168 170 101 150 89 50 29 0 0
Emp6 84 84 98 60 71 10 12 4 4
Emp7 168 175 104 155 92 20 12 0 0
G Total 1092 1108 101 940 86 190 17 12 1
But I get this:
Total Employee Req Hrs Rep Hrs % Billable hrs % NonBill Hrs % Time Off %
Dept A Total 1684 1675 101 1250 86 225 17 12 1
Emp1 168 170 101 150 89 50 29 0 0
Emp2 168 165 98 120 71 20 12 8 4
Emp3 168 175 104 155 92 20 12 0 0
Emp4 168 170 101 150 89 50 29 0 0
Dept B Total 1092 1108 101 1250 86 225 17 12 1
Emp5 168 170 101 150 89 50 29 0 0
Emp6 84 84 98 60 71 10 12 4 4
Emp7 168 175 104 155 92 20 12 0 0
G Total 1092 1108 101 940 86 190 17 12 1
The totals are correct but the % is wrong.
I have several Datasets because the report only runs the department you are in, except for the VPs who can see all departments.
I Insert the percentage columns into the matrix and have tried several expressions with no results including:
=Fields!ActHrs.Value/Fields!ReqHrs.Value
=Sum(Fields!ActHrs.Value, "Ut_Query")/Sum(Fields!ReqHrs.Value, "Ut_Query")
=Sum(Fields!ActHrs.Value, "Ut_Query","Dept")/Sum(Fields!ReqHrs.Value,
"Ut_Query","Dept")
=Sum(Fields!ActHrs.Value,"Dept", "Ut_Query")/Sum(Fields!ReqHrs.Value,
"Dept","Ut_Query")
Plus more I can't even remember.
I tried creating new groups, and even a new matrix.
There must be a simple way to get the percentage by group but I have not found an answer on any of the interned boards.
OK, I figured this out, but it doesn't make much sense. If I try:
=Textbox29/TextBox28 I get error messages about undefined variables.
If I go the the textbox properties and rename the textboxes to Act and Req and use:
=Act/Req I get the right answer.

How to find the last six rows(dynamic) sum of one column based on another column

BallByBallID Deliveries RunsScored BowlPlayerId BatPlayerId
109 0 1 127 4
110 0.1 2 127 6
111 0.2 3 127 6
112 0.3 4 127 4
113 0.4 6 127 4
114 0.5 6 127 4
230 0 1 162 4
231 0.1 2 162 6
232 0.2 3 162 6
233 0.3 4 162 4
234 0.4 5 162 4
235 0.5 6 162 6
236 1 1 169 4
237 1.1 2 169 6
238 1.2 3 169 6
239 1.3 4 169 4
240 1.4 5 169 4
241 1.5 6 169 6
I have data in the above mentioned format. Now i want to find the sum of RunsScored and BowlPlayerId for last inserted data (the data is dynamic the last six may change at any time) based on BallByBallId.
I tried to find the solution by using like this.........
SELECT SUM(RunsScored) from (select BallByBallId from BallByBall ORDER BY BallByBallId DESC LIMIT 6);
It is giving total some......
SELECT SUM(RunsScored) from (SELECT top 6 * from BallByBall ORDER BY BallByBallId DESC) A GROUP BY A.BowlPlayerID
SELECT SUM(RunsScored+BowlPlayerID)
FROM from BallByBall group by BallByBallId limit 6;
http://sqlfiddle.com/#!2/f3ab78/10

select query to get those result where for every unique value of column 3, column 2 has bothval1 and val2

MEMO TYPE ID
2442 11 52
33658 4 52
823 6 56
825 4 56
826 7 56
85 4 57
3298 7 57
87 4 141
377 7 141
88 4 142
378 7 142
98 1 143
99 2 143
194 7 143
7586 5 143
1451 4 143
7781 6 143
3252 4 167
3249 6 167
3915 7 167
13666 5 167
115 4 168
9253 9 168
9254 10 168
138 1 194
139 2 194
1951 4 194
8650 7 194
8191 6 197
8192 7 197
9687 8 197
9930 9 197
I need to select those records from above table where for every unique value in column 'ID', column 'TYPE' have value 6 and 7 both.
Result of this select query would be as below:
MEMO TYPE ID
823 6 56
826 7 56
7781 6 143
194 7 143
3249 6 167
3915 7 167
8191 6 197
8192 7 197
I hope this data is not too much.
select t.*
from your_table t
inner join
(
select id, min(type) as mint, max(type) as maxt
from your_table
where type in (6,7)
group by id
having count(distinct type) = 2
) x on x.id = t.id and t.type in (x.maxt,x.mint)
SQLFiddle demo