MYSQL filter our same rows that are next to each other - mysql

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)

Related

I want to return the number of rows it's been since a value occurred

Alright, I'm starting over with a new bit of code that feels more efficient and shows that I can get some of what I want but not the final bit. Here is the edited code:
SELECT
uq1.UserID,
uq1.QuestionID,
r.LastAttempt,
r.Score,
r.DateSeen,
s.LastBad,
s.Score AS ScoreUnder,
s.DateSeen AS DateScoreUnder
FROM
users_questions uq1
LEFT JOIN (
SELECT
uq2.QuestionID,
uq2.UserID,
MAX(UsersQuestionsID) LastAttempt,
uq2.Score,
uq2.DateSeen
FROM
users_questions uq2
GROUP BY
uq2.UserID,
uq2.QuestionID
) AS r ON r.QuestionID = uq1.QuestionID AND r.UserID = uq1.UserID
LEFT JOIN (
SELECT
uq3.QuestionID,
uq3.UserID,
MAX(UsersQuestionsID) LastBad,
uq3.Score,
uq3.DateSeen
FROM
users_questions uq3
WHERE
uq3.Score <= 250
GROUP BY
uq3.UserID,
uq3.QuestionID
) AS s ON s.QuestionID = uq1.QuestionID AND s.UserID = uq1.UserID
GROUP BY
uq1.UserID,
uq1.QuestionID
It seems to be more efficient and produce some of what I want. The thing I need to find is the number of iterations between the record that it displays on the last LEFT JOIN and the end of the table for each question and user combo.
My test data is this:
UsersQuestionsID
Score
DateSeen
UserID
QuestionID
1
877
2022-06-25 19:51:18
14
98
2
765
2022-06-25 15:52:42
14
99
3
345
2022-06-25 15:54:22
14
99
4
754
2022-06-25 15:54:22
14
107
5
222
2022-06-25 16:11:40
13
73
6
525
2022-06-25 16:11:40
13
55
7
23
2022-06-25 16:11:40
13
130
8
888
2022-06-25 16:11:40
13
104
9
234
2022-07-01 12:41:44
14
94
10
564
2022-07-01 12:41:44
14
106
11
0
2022-07-01 13:59:37
14
99
12
267
2022-07-01 16:57:40
14
99
13
345
2022-07-02 15:17:03
13
99
14
49
2022-07-02 17:44:19
14
99
15
222
2022-07-02 18:10:17
14
99
16
49
2022-07-02 18:10:43
14
94
17
1000
2022-07-02 18:11:18
14
106
18
0
2022-07-06 14:18:51
14
94

mysql: how to select group by first character and top 5 by counter

my table look like following
id person counter
1 Ona 4946
2 Mayra 15077
3 Claire 496
4 Rita 13929
5 Demond 579
6 Winnifred 13580
7 Green 1734
8 Jacquelyn 19092
9 Aisha 5572
10 Kian 8826
11 Alexandrea 7514
12 Dalton 14151
13 Rossie 18403
14 Carson 19537
15 Mason 2022
16 Emie 2394
17 Jonatan 6655
18 June 5037
19 Jazmyn 10856
20 Mittie 18928
here is the fiddle
i would like to select the top 5 by counter and group by first character, here is the sql that i tried:
SELECT SUBSTR(person,1,1) AS Alpha, person, counter
FROM myTable
GROUP BY SUBSTR(person,1,1)
ORDER BY SUBSTR(person,1,1) ASC, counter DESC;
how to select desired result as following:
alpha person counter
a Arvid 9236
a Aisha 5572
a Alf 4000
a Ahmad 3500
a Alvin 2100
b Brandon 13000
b Ben 8230
b Bonny 7131
b Bella 4120
b Bun 1200
c Connie 9320
c Calvin 8310
c Camalia 6123
c Cimon 3419
c Clay 2515
im using mysql 8.0
You can do:
select *
from (
select *, row_number() over(partition by substr(person, 1, 1)
order by counter desc) as rn
from myTable
) x
where rn <= 5
order by substr(person, 1, 1), rn
Result:
id person counter rn
---- ---------- -------- --
153 Alf 19758 1
283 Alycia 19706 2
260 Abe 19463 3
223 Assunta 18808 4
300 Ari 18031 5
210 Bennie 18309 1
159 Barry 18281 2
128 Beulah 18080 3
314 Benny 16795 4
474 Barry 15789 5
342 Casandra 19656 1
14 Carson 19537 2
67 Chaim 19429 3
280 Colin 18507 4
500 Corbin 18433 5
380 Daphney 19138 1
234 Dejah 18781 2
241 Derrick 18722 3
49 Dasia 18562 4
312 Darrel 17903 5
163 Evalyn 19847 1
79 Ernestine 19523 2
344 Emilie 19520 3
371 Eva 19119 4
469 Emma 18403 5
140 Fiona 19522 1
216 Flo 18314 2
356 Frieda 16082 3
254 Floy 15942 4
54 Florencio 12739 5
447 Geoffrey 19858 1
327 Geoffrey 19223 2
335 Grant 19100 3
454 Giuseppe 16175 4
83 Gardner 15235 5
373 Hilario 19507 1
35 Hanna 19276 2
200 Halle 18150 3
491 Hailee 17521 4
411 Hermann 17018 5
21 Idella 7440 1
177 Izabella 5536 2
115 Isai 4164 3
412 Izabella 2112 4
275 Imani 573 5
195 Joannie 19374 1
8 Jacquelyn 19092 2
48 Jalon 18861 3
251 Jamie 18768 4
367 Joanny 17600 5
282 Kendra 19278 1
421 Kendra 19213 2
363 Kaylin 18977 3
96 Kaylie 18423 4
310 Katrine 17754 5
146 Lonzo 19778 1
194 Leonora 18258 2
399 Laurine 16847 3
137 Leslie 16718 4
190 Luther 16318 5
87 Maegan 19112 1
20 Mittie 18928 2
271 Mariana 18149 3
317 Mary 18043 4
305 Maybelle 17666 5
281 Noelia 19203 1
176 Nickolas 19047 2
408 Nelson 15901 3
142 Nasir 13700 4
366 Nicole 10694 5
423 Ova 19759 1
487 Osborne 19539 2
438 Ozella 18911 3
375 Ora 18270 4
414 Onie 17358 5
52 Pascale 19658 1
39 Pearlie 17621 2
364 Price 14177 3
161 Precious 10337 4
294 Paula 9162 5
70 Quincy 18343 1
73 Quincy 16631 2
192 Quentin 13578 3
131 Rodger 19776 1
231 Royal 19033 2
313 Rocky 19008 3
13 Rossie 18403 4
45 Rosanna 15992 5
418 Sydnee 19810 1
470 Sadie 19189 2
123 Shanna 18862 3
485 Savanah 18664 4
302 Steve 16412 5
406 Toney 18283 1
28 Tremaine 16400 2
98 Taurean 15911 3
278 Tremaine 14391 4
311 Treva 14026 5
239 Ubaldo 11630 1
78 Valentina 17736 1
458 Vita 17527 2
170 Vergie 16971 3
158 Vance 15089 4
272 Veronica 12027 5
102 Willis 18155 1
329 Ward 14919 2
156 Westley 14867 3
136 Winnifred 14315 4
6 Winnifred 13580 5
323 Yolanda 17920 1
155 Yesenia 6164 2
402 Zachary 19129 1
37 Zaria 5398 2
See running example at DB Fiddle.

prize distribution on the basis of rank using 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.

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

Selecting duplicate entries from a table and getting all the fields from the duplicate rows

I have a table like this.
id day1 day2 day3
1 411 523 223
2 413 554 245
3 417 511 209
4 420 515 232
5 422 522 212
6 483 567 212
7 456 512 256
8 433 578 209
9 438 532 234
10 418 555 223
11 460 510 263
12 453 509 245
13 441 524 233
14 430 543 261
15 456 582 222
16 444 524 241
17 478 511 211
18 421 583 222
I want to select all the IDs that have duplicate values in day2.
I'm doing
select day2,count(*) from resultater group by day having count(*)>1;
Is it possible to list all the IDs within the groups?
select day2,count(*), group_concat(id)
from resultater
group by day
having count(*)>1;
should do the trick.