MySQL recursive query for counting - mysql

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!

Related

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

SQL: Split Dataset into two columns

I have a table like this:
id c_id time value
1 4 1 12
2 4 2 5
3 4 3 6
4 4 4 48
5 4 5 1
6 4 6 121
7 5 1 121
8 5 2 321
9 5 3 2
10 5 4 1
11 5 5 54
12 5 6 4546
13 5 7 78
14 5 8 784
15 5 9 1
Now I want a table like this with a SELECT command:
time1 value1 time2 value2
1 12 1 121
2 5 2 321
3 6 3 2
4 48 4 1
5 1 5 54
6 121 6 4546
0 0 7 78
0 0 8 784
0 0 9 1
time1 and value1 is from the data with c_id=4,
time2 and value2 is from the data with c_id=5
Is it possible to create a SELECT command to do that?
I hope you can help
Yiu can use an inner join
select a.time as time1, a.value as value1, b.time as time2, b.value as value2
from my_table as a
inner join my_table as b on a.time = b.time
and a.c_id= 4
and b.c_id= 5;

Pivot tables in mysql columns

I have table localbanya ,I wanted to do pivoting of its column, Here is my table structure
Billingid prod_id qty
1 11 2
1 22 5
2 11 1
2 22 3
2 33 4
3 11 2
3 22 1
I'm expecting something like this
Billinid 11 22 33 Total
1 2 5 0 2+5+0
2 1 3 4 1+3+4
3 2 1 0 2+1+0
I have tried this but unable to get the desired result
SELECT billingid,GROUP_CONCAT(qty)
FROM localbanya
GROUP BY billingid;
please help, Thanks in advance

sql display in matrix form but column and row values not fixed

tables i am using
product_parameter
id productid parameterid value
1 1 1 10
2 2 2 11
3 1 2 34
4 2 4 44
5 3 2 55
6 3 3 43
7 4 1 33
8 1 3 33
9 1 4 24
and so on i want to display in form
parameterid 1 2 3 4. . .
productid
1 43 34 33 24
2 null 11 null 44
3
4
.
.
and so on rows and columns are not fixed
tables i am using
product_parameter
Sorry wanted to correct the output format i needed after query
id productid parameterid value
1 1 1 10
2 2 2 11
3 1 2 34
4 2 4 44
5 3 2 55
6 3 3 43
7 4 1 33
8 1 3 33
9 1 4 24
and so on i want to display in form
parameterid 1 2 3 4. . .
productid
1 43 34 33 24
2 null 11 null 44
3
4
.
.
and so on... rows and columns values are not fixed
It would be much easier to create 2D array in application code.
In SQL you have to add a join for each column.

Selecting items from one column based on values in another.

I have the following data:
id1,id2
1 3
1 8
1 10
1 11
2 3
2 10
2 11
3 2
3 18
3 20
4 3
4 8
5 3
5 10
5 11
5 40
5 45
5 50
6 1
6 59
6 70
I won't get all id1 with id2 = 3,10,11.
For example, id1=4 only with id2=3, should not return.
The results should be
id1
1
2
5
SELECT distinct(ID1) FROM TBTEST WHERE ID2 IN(3,10,11)
SQL code
SELECT ID1,COUNT(ID2) FROM TBTEST
WHERE ID2 IN(3,10,11)
GROUP BY ID1
HAVING COUNT(ID2)=3
Is this what you need?