how can I make this sql join request - mysql

How can get this : the last name (nom), first name (prenom) and age of competitors that participated at all competitons. I have difficulties with count and join.
my user table :
id
nom
prenom
login
age
1
Wehner
Einar
kleinviola
79
2
Beer
Cierra
earnestinelebsa
71
3
Gina
Lucien
cassindagmar
97
4
Maybelle
Delphine
haleypredovic
91
5
Upton
Elwyn
sstreich
63
6
Irwin
Prof.
christopframi
25
7
Ernser
Clint
cesar65
83
8
Bechtelar
Sheila
sofiasawayn
77
9
Simonis
Remington
christafahey
35
10
Parisian
Octavia
swiftsage
89
11
Predovic
Rory
bartolettisabri
78
12
Will
Sven
price66
20
13
O'Hara
Zoey
tiffanywillms
96
14
McGlynn
Julie
gkoss
74
15
Walter
Maximus
amandajenkins
63
16
Hahn
Andrew
drutherford
77
17
Kunze
Elinore
ziemanntheron
95
18
Ursula
Evelyne
collierodessa
64
19
Klein
Kirsten
darrellrunolfss
96
20
Chester
Lucien
jamey55
24
21
Darron
Antoine
justina27
60
22
Boyer
Harvey
hesseljameson
45
23
Jade
Lucien
kpagac
29
24
Eliane
Delphine
delphahessel
75
25
Lang
Shanna
sophia73
23
26
Wilderman
Fredrick
shaina75
34
27
Daniel
Emie
alene73
86
28
Daniel
Rhoda
foster22
63
29
Trantow
Tommie
boconner
40
30
Kerluke
Adolf
vstanton
74
31
Sehoubo
David
davidshbo
20
32
dfglskdsklj
dfvdvf
dfgdfg
0
my competitors table :
id_competitor
id_concours
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
31
1
9
2
10
2
11
2
12
2
13
2
14
2
15
2
16
2
17
2
18
2
31
2
1
3
2
3
3
3
4
3
5
3
19
3
20
3
31
3
2
4
4
4
6
4
8
4
10
4
12
4
14
4
16
4
18
4
20
4
1
5
3
5
5
5
7
5
9
5
11
5
13
5
15
5
17
5
19
5
my competitons table:
id
date_debut
date_fin
descriptif
theme
etat
1
2019-01-01 00:00:00
2019-03-01 00:00:00
Le premier concours de la plateforme
Les zinzins de l'espace
4
2
2018-01-01 00:00:00
2018-02-01 00:00:00
Le deuxième concours de la plateforme
Outils
4
3
2020-04-01 00:00:00
2020-05-01 00:00:00
Le troisième concours de la plateforme
Voiture sur autoroute
2
4
2018-07-01 00:00:00
2018-08-11 00:00:00
Le quatrième concours de la plateforme
Naruto Uzumaki
3
5
2018-10-01 00:00:00
2018-11-01 00:00:00
Le cinquième concours de la plateforme
Le grand peuple au dessus de la mer
4

This should return the name, first name and age of all users that participated in ALL competitions:
SELECT nom, prenom, age
FROM user
WHERE (SELECT count(DISTINCT id_concours) FROM competitors WHERE id_competitor = user.id) = (SELECT count(*) FROM competitons);

Related

How sort a table based on age, and extract the top 2 user's address on mysql?

I have a table like this
create table users(
user_id int not null auto_increment,
user_age date,
user_address varchar(255),
primary key(user_id)
)
user_id
user_age
user_address
1
2010-01-05
87 Polk St. Suite 5
2
2010-01-06
Carrera 52 con Ave. Bolivar #65-98 Liano Largo
3
2010-01-07
Ave. 5 de Mayo Porlamar
4
2010-01-08
89 Chiaroscuro Rd.
5
2010-01-09
Via Ludovico il Moro 22
6
2010-01-10
Rue JosephBens 532
7
2011-01-05
43 rue St. Laurent
8
2011-01-06
Heerstr. 22
9
2011-01-07
South House 300 Queensbridge
10
2011-01-08
Ing. Gustavo Moncaa 8585 Piso 20-A
11
2011-01-09
Obere Str. 57
12
2011-01-10
Avda. de la Constitución 2222
13
2012-01-05
Mataderos 2312
14
2012-01-06
120 Hanover Sq.
15
2012-01-07
Berguvsvägen 8
16
2012-01-08
Forsterstr. 57
And I'd like my table to be like this:
user_id
user_age
user_address
1
2010-01-05
87 Polk St. Suite 5
2
2010-01-06
Carrera 52 con Ave. Bolivar #65-98 Liano Largo
7
2011-01-05
43 rue St. Laurent
8
2011-01-06
Heerstr. 22
13
2012-01-05
Mataderos 2312
14
2012-01-06
120 Hanover Sq.
How can I make this happen with group by statement?
If your MySQL supports windows function try:
with cte as
(
SELECT *, ROW_NUMBER() OVER(partition by year(user_age) ORDER BY user_age) row_num
FROM users
)
select user_id,user_age,user_address
from cte
where row_num<=2;
Demo

Mysql 'nested set' method for hierarchical data returns wrong parent name in -some- rows

I have the following 'nested set' data in a table.
ID
name
lft
rgt
main
1
Occasion uurwerken
1
28
1
2
Mechanisch
2
27
3
Alpine
3
4
4
AS
5
6
5
Durowe
7
8
6
Enicar
9
10
7
ETA
11
12
8
FE
13
14
9
FEF
15
16
10
Felsa
17
18
11
FHF
19
20
12
Otero
21
22
13
Peseux
23
24
14
PUW
25
26
15
Nieuwe uurwerken
29
60
1
16
Quartz
30
47
17
Catlin
31
32
18
Citizen
33
34
19
ESA
35
36
20
FE
37
38
21
GUB
39
40
22
Miyota
41
42
23
Parrenin
43
44
24
Ronda
45
46
25
Mechanisch
48
59
26
Enicar
49
50
27
FE
51
52
28
FHF
53
54
29
Pesseux
55
56
30
Ronda
57
58
31
Vintage occasion
61
66
1
32
Certina stemvork
62
63
33
Tissot stemvork
64
65
I have this query to retrieve the data I need for building a menu
SELECT parent.name AS parentname, node.id, node.name AS name, node.lft, node.rgt, (
COUNT( parent.name ) -1) AS depth
FROM nested_menu AS node, nested_menu AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.id
ORDER BY node.lft";
Which works fine and returns the following data
parentname
ID
name
lft
rgt
depth
Occasion uurwerken
1
Occasion uurwerken
1
28
0
Occasion uurwerken
2
Mechanisch
2
27
1
Occasion uurwerken
3
Alpine
3
4
2
Occasion uurwerken
4
AS
5
6
2
Occasion uurwerken
5
Durowe
7
8
2
Occasion uurwerken
6
Enicar
9
10
2
Occasion uurwerken
7
ETA
11
12
2
Occasion uurwerken
8
FE
13
14
2
Occasion uurwerken
9
FEF
15
16
2
Occasion uurwerken
10
Felsa
17
18
2
Occasion uurwerken
11
FHF
19
20
2
Occasion uurwerken
12
Otero
21
22
2
Occasion uurwerken
13
Peseux
23
24
2
Occasion uurwerken
14
PUW
25
26
2
Nieuwe uurwerken
15
Nieuwe uurwerken
29
60
0
Nieuwe uurwerken
16
Quartz
30
47
1
Nieuwe uurwerken
17
Catlin
31
32
2
Nieuwe uurwerken
18
Citizen
33
34
2
Nieuwe uurwerken
19
ESA
35
36
2
Nieuwe uurwerken
20
FE
37
38
2
Nieuwe uurwerken
21
GUB
39
40
2
Nieuwe uurwerken
22
Miyota
41
42
2
Nieuwe uurwerken
23
Parrenin
43
44
2
Nieuwe uurwerken
24
Ronda
45
46
2
Nieuwe uurwerken
25
Mechanisch
48
59
1
Nieuwe uurwerken
26
Enicar
49
50
2
Nieuwe uurwerken
27
FE
51
52
2
Nieuwe uurwerken
28
FHF
53
54
2
Pesseux
29
Pesseux
55
56
2
Ronda
30
Ronda
57
58
2
Vintage occasion
31
Vintage occasion
61
66
0
Certina stemvork
32
Certina stemvork
62
63
1
Tissot stemvork
33
Tissot stemvork
64
65
1
Which seems fine, but in the rows with ID 29 and 30 the parent name is suddenly the same as the node name and I have no clue why?

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.

what's the most efficient way to manage record position in a RDBMS table

let's say we have records in a table and we would like to be able to order (and reorder them).
the table could look like something like this, see below
id Pos Level parentId
Europe 18 1 0 null
Germany 9 2 1 18
Berlin 2 3 2 9
Frankfurt 20 4 2 9
Stuttgart 23 5 2 9
France 29 6 1 18
Paris 26 7 2 29
Lyon 13 8 2 29
Americas 11 9 0 null
USA 27 10 1 11
New York 22 11 2 27
Manhattan 19 12 3 22
Brooklyn 7 13 3 22
Los Angeles 25 14 2 27
Mexico 6 15 1 11
Canada 4 16 1 11
Montreal 21 17 2 4
Vancouver 3 18 2 4
Asia 8 19 0 null
China 14 20 1 8
Beijing 17 21 2 14
Shenzhen 30 22 2 14
Shanghai 28 23 2 14
Japan 16 24 1 8
Tokyo 1 25 2 16
Shinjuku 15 26 3 1
Oceania 24 27 0 null
Autralia 5 28 1 24
Sydney 10 29 2 5
Africa
12 30 0 null
where id is a unique id (can be anything), position the position of the element in the list, level depth level and parentId parent id (if exists)
Typically I would want the following method:
/**
#param sourceId: id of the element to be moved
#params targetId: id of the element which position needs to be overtaken
#param aboveOrBelow: defines whether the old element (target) will be placed above or below the source element
#return if successful, new position of the source element, if unsuccessful: message explaining why unsuccessful
*/
def move(sourceId: Long, targetId: Long, aboveOrBelow: Boolean = true):Either[Long, String]
what's the most efficient way to implement this or am I missing something? Is there already a built-in mechanism for such operations in (My)SQL?
constraints:
- end user who might be allowed to reorder do not necessarily see all records (e.g. only asian records)
- records can be added and deleted
=== edit ===
i rewrote the structure taking in account suggestions in the comments:
id pos parentId
Europe 18 1 null
Germany 9 1 18
Berlin 2 1 9
Frankfurt 20 2 9
Stuttgart 23 3 9
France 29 2 18
Paris 26 1 29
Lyon 13 2 29
Americas 11 2 null
USA 27 1 11
New York 22 1 27
Manhattan 19 1 22
Brooklyn 7 2 22
Los Angeles 25 2 27
Mexico 6 3 11
Canada 4 4 11
Montreal 21 1 4
Vancouver 3 2 4
Asia 8 3 null
China 14 1 8
Beijing 17 1 14
Shenzhen 30 2 14
Shanghai 28 3 14
Japan 16 2 8
Tokyo 1 1 16
Shinjuku 15 1 1
Oceania 24 4 null
Autralia 5 1 24
Sydney 10 1 5
Africa 12 5 null
And for constructing the tree structure i would use recursive cte as follows. and construct it as a view
with recursive cte(place_name,id,parent_id,level)
as (select place_name,id,parent_id,1 as level
from countries_hierarchy
where parent_id is null
union all
select concat(lpad(' ',a.level+1,' ')
,b.place_name
)
,b.id
,b.parent_id
,a.level+1
from cte a
join countries_hierarchy b
on a.id=b.parent_id
)
select * from cte
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=334820e4e01cf8749c5abcaa447963a0

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)