Only show the highest amount on an INNER JOIN - mysql

We have an interactive Map of America which shows the state which equals your requirement.
We have an Problem with our Database, we have two tables staaten and economydata.
Our inner join
SELECT staaten.staat_id, staat_name, economydata.INDUSTRY_ID, economydata.INDUSTRIE_UMSATZ_ANTEIL
FROM staaten, economydata
WHERE staaten.staat_id = economydata.staat_i;`
gives us this output:
staat_id staat_name INDUSTRY_ID INDUSTRIE_UMSATZ_ANTEIL
1 Alabama 3 1
1 Alabama 6 1
1 Alabama 10 3
1 Alabama 11 4
1 Alabama 12 18
1 Alabama 13 11
1 Alabama 25 7
1 Alabama 34 6
1 Alabama 35 7
1 Alabama 36 3
1 Alabama 45 2
1 Alabama 51 5
1 Alabama 56 11
1 Alabama 60 6
1 Alabama 64 1
1 Alabama 65 3
1 Alabama 69 1
1 Alabama 70 7
1 Alabama 75 0
1 Alabama 78 3
1 Alabama 81 3
1 Alabama 82 17
2 Alaska 3 2
2 Alaska 6 16
2 Alaska 10 2
2 Alaska 11 4
2 Alaska 12 3
2 Alaska 13 0
2 Alaska 25 3
2 Alaska 34 2
2 Alaska 35 4
2 Alaska 36 12
2 Alaska 45 3
2 Alaska 51 3
2 Alaska 56 9
2 Alaska 60 4
2 Alaska 64 1
2 Alaska 65 2
2 Alaska 69 0
2 Alaska 70 7
2 Alaska 75 1
2 Alaska 78 3
2 Alaska 81 2
2 Alaska 82 21
But we only need one row per Staate which only contains the Highest economydata.INDUSTRIE_UMSATZ_ANTEIL with the INDUSTRY_ID.
The closest we got was with SELECT ... MAX(economydata.INDUSTRIE_UMSATZ_ANTEIL) FROM ... GROUP BY staaten.staat_name but we lost the connection between economydata.INDUSTRIE_UMSATZ_ANTEIL and INDUSTRY_ID, it showed us the Highest INDUSTRIE_UMSATZ_ANTEIL but not the right INDUSTRY_ID

You could use a tuple and a in clause on the result for max(INDUSTRIE_UMSATZ_ANTEIL) group by staat_id
SELECT
staaten.staat_id
, staat_name
, economydata.INDUSTRY_ID
, economydata.INDUSTRIE_UMSATZ_ANTEIL
FROM staaten
INNER JOIN economydata on staaten.staat_id = economydata.staat_i
where (staaten.staat_id, economydata.INDUSTRIE_UMSATZ_ANTEIL ) in (
SELECT
staaten.staat_id
, max(economydata.INDUSTRIE_UMSATZ_ANTEIL)
FROM staaten
INNER JOIN economydata on staaten.staat_id = economydata.staat_i
group by staaten.staat_id
)
and i suggest the use of explicit join instead that where clause ... the code is more clear

Related

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 recursive query for counting

i am trying to find a single query for my desired output and cannot get my head around it if it is at all possible..
table_forum:
forum_id parent_id forum_name
1 0 name1
2 1 name2
7 0 name3
8 7 name4
9 7 name5
173 9 name6
11 0 name7
12 0 name8
233 11 name9
14 11 name10
...
table_posts:
post_id topic_id forum_id poster_id
25626 61 1 85
2 1 1 85
3 1 1 85
4 1 1 85
5 1 1 85
6 1 1 85
7 200 7 85
8 19 8 85
9 4 9 85
10 2 173 85
196122 3202 233 85
11 2 173 85
12 2 173 85
...
I made a quick Fiddle for you to be able to test how far I came with: http://sqlfiddle.com/#!9/90b73f/1
Atm I can get one forum and all its parents with the posts counted upward but only from that forum upwards (no other forums get into the calculation)
What I would like to achieve is an sql output like this:
forum_id forum_name parent_id lvl countPosts
1 name1 0 2 6
2 name2 1 1 0
7 name3 0 3 5
8 name4 7 2 1
9 name5 7 2 4
173 name6 9 1 3
11 name7 0 2 1
14 name10 11 1 0
233 name9 11 1 1
12 name8 0 1 0
I don't know if that's possible but I would like "lvl" to use later on as a counter for "\t" to indent the name of the forum, to better visualize on my site how the forums are assigned...
I want to later present it on the webpage in a table kind of like this (without bullet characters):
forumname Postcount
name1 6
name2 0
name3 5
name4 1
name5 4
name6 3
etc...
If you have any better solution as to how you would approach the problem, I am all ears! - This is the first encounter with such a problem so I couldn't think of another way.
Thanks in advance!

MySql Count the same value

I have this table. My task is this : Count the students having the same first name.
I want it to show me just the firstname and then how many times firstname is found:
like this: bob | 2
id firstN lastN group grade tax gender year university
9 Alyson Hanniga 112 1 0 female 1 UTC
5 Barney Stinson 111 4 0 male 1 UBB
8 Bob Saget 111 6 900 male 3 UBB
14 Bob Bob 112 10 250 male 1 UBB
11 Cobie Smulder 111 9 200 female 1 Dragos Voda
7 David Henrie 112 9 0 male 1 Dragos Voda
12 Jason Segel 112 10 150 male 1 UTC
13 Josh Radnor 112 7 0 male 2 Dragos Voda
4 Lily Aldrin 112 5 400 female 1 UBB
6 Lyndsy Fonseca 113 10 0 female 3 UTC
2 Marshal Eriksen 112 10 100 male 2 UTC
10 Neil Patrick 112 7 0 male 3 Dragos Voda
1 Robin Scherba 111 10 0 female 1 UBB
3 Ted Mosby 112 8 0 male 2 UBB
Here is query for
select FirstName,count(*) from tblStudent group by FirstName

Query to find the running sum of a column(qty) based on type(if 'a' add else subtract)

I have table with data as follows:
Store ItemNo Type Billno Qty
London 1 A 1 10
London 1 A 2 5
London 1 S 1 7
London 1 A 3 5
London 1 S 2 7
London 2 A 1 19
London 2 S 2 5
London 2 A 3 11
Paris 1 A 1 15
Paris 1 S 2 8
Paris 1 A 3 9
Paris 2 A 1 10
Paris 2 S 2 5
Now i want to calculate TotalQty, such that totalqty of qty of an itemno under particular store is calculated based on type. i.e. if type is A, qty should be added to total and if it is S , subtracted from total as shown below. In the example below for store london ,itemno 1 row 3 is the last entry,so the totalQty gives the current quantity availble for that item in that particular store.
Store ItemNo Type BillNo Qty TotalQty
London 1 A 1 10 10
London 1 A 2 5 15
London 1 S 1 7 8
London 1 A 3 5 13
London 1 S 2 7 6
London 2 A 1 19 19
London 2 A 2 5 24
London 2 S 3 11 13
Paris 1 A 1 15 15
Paris 1 S 2 8 7
Paris 1 A 3 9 16
Paris 2 A 1 10 10
Paris 2 S 2 5 5
Assuming I understand you right, you need to use the IIf statement:
SELECT Store, ItemNo, SUM(IIF(Type = 'A', Qty, 0 - Qty)) AS TotalQty
FROM MyTable
GROUP BY Store, ItemNo
should produce the following (untested):
Store ItemNo TotalQty
London 1 8
London 2 13
Paris 1 16
Paris 2 5
I think this is it (I was confused but then spotted your data is inconsistent between table and results):
SELECT S1.Store, S1.ItemNo, S1.Type, S1.Billno, S1.Qty,
(
SELECT SUM(SWITCH(
S2.Type = 'A', S2.Qty,
S2.Type = 'S', 0 - S2.Qty,
TRUE, NULL
))
FROM StoreStuff AS S2
WHERE S2.Store = S1.Store
AND S2.ItemNo = S1.ItemNo
AND S2.Billno <= S1.Billno
) AS TotalQty
FROM StoreStuff AS S1
ORDER
BY S1.Store, S1.ItemNo, S1.Billno;