How to write SQL subqueries with count? - sql

I'm using mysql. I want to count the minimum, maximum, and average number of different tags per movie from one table.
Exclude the duplicate:
same tag given by the same user to the same movie
same tag given by different users to the same movie
Example: table 'tags'
userId
movieId
tag
1
1
crime
1
2
dark
1
2
dark
2
2
greed
2
2
dark
3
3
music
3
3
dance
3
3
quirky
4
3
dance
4
3
quirky
Expect result:
movieId
Min_Tag
Max_Tag
Avg_Tag
1
1
1
1
2
1
2
0.66...
3
1
2
0.6
I try to write query like below, but it shows an error.
SELECT
DISTINCT movieId,
MIN(COUNT(DISTINCT tag) AS Min_Tag,
MAX(COUNT(DISTINCT tag) AS Max_Tag,
AVG(COUNT(DISTINCT tag) AS Avg_Tag,
FROM (
SELECT userId,movieId,tag
FROM tags
GROUP BY userId, movieId, tag
) AS non_dup
GROUP BY movieId;

You have to rewrite your query
First you need the count per tag and movie
and fromm that you can calculate min max and avg
SELECT
movieId,
MIN(count_tag) AS Min_Tag,
MAX(count_tag) AS Max_Tag,
AVG(count_tag) AS Avg_Tag
FROM
(SELECT movieId,tag, count(*) count_tag
FROM tags
GROUP BY movieId, tag) non_dup
GROUP BY movieId
movieId
Min_Tag
Max_Tag
Avg_Tag
1
1
1
1.0000
2
1
3
2.0000
3
1
2
1.6667
fiddle

Related

create pivot table using sql

I have a database called player.db
These database has two tables.
The tables called person and the other is called match.
person table is
Player_ID
Player
Country
1
Lionel Messi
Argentina
2
Luis Suarez
Uruguay
3
Neymar
Brazil
match table is
Match _ID
Game
Player_ID
Date
Season
1
Uruguay-Paraguay
2
5/3/2019
1
2
Uruguay-Chile
2
19/3/2019
1
3
Argentina-Chile
1
22/3/2019
1
4
Brazil-Guyana
3
3/4/2019
1
5
Brazil-USA
3
1/6/2020
2
6
Brazil-Belize
3
3/7/2020
2
7
Brazil-Suriname
3
5/7/2020
2
8
Argentina-USA
1
8/8/2020
2
9
Argentina-Canada
1
3/3/2021
3
10
Argentina-Grenada
1
8/3/2021
3
11
Uruguay-Suriname
2
7/4/2021
3
12
Uruguay-Mexico
2
2/2/2022
4
13
Uruguay-Jamaica
2
4/2/2022
4
14
Brazil-Ecuador
3
5/2/2022
4
My pivot table should look like these:
Season
Player
1
Luis Suarez
2
Neymar
3
Lionel Messi
4
Luis Suarez
I want a sql code which create a pivot table which shows which player played most with topscore in which season year. For example Luis Suarez occured most in season 1.
I started coding in sql, but got not the desired solution
SELECT Player_ID, COUNT(*)FROM match GROUP BY Player_ID HAVING COUNT(*) max
The problem is I got an error and it doesn't create a pivot table which show which player played most in which season.
Join the tables, group by season and player to get the number of matches for each player and use FIRST_VALUE() window function to pick the top player of each season:
SELECT DISTINCT m.Season,
FIRST_VALUE(p.Player) OVER (PARTITION BY m.Season ORDER BY COUNT(*) DESC) Player
FROM match m INNER JOIN person p
ON p.Player_ID = m.Player_ID
GROUP BY m.Season, m.Player_ID;
See the demo.
Your clause HAVING count(*) max may cause the error.
The solution may depend on the relational data base you use. Here is a solution with postgresql :
SELECT DISTINCT ON (Season)
m.season, p.player, count(*) AS count
FROM match AS m
INNER JOIN player AS p ON p.player_ID = m.Player_ID
GROUP BY m.Season, p.Player_ID, p.player
ORDER BY m.Season ASC, count DESC
see dbfiddle

Select columns from a table and count a value from another table

I have the following tables:
table_user
id
name
1
Arnold
2
Wesley
3
Abel
4
Harry
5
Cristiano
table_post
fk_user is from user who created the post
id
fk_user
title
description
1
2
Movie
I like horror movies
2
4
Music
Music is essential to my days
3
4
Soccer
The World Cup is coming!
table_post_like
fk_user is from user who liked the post
fk_post
fk_user
1
1
1
3
1
4
1
5
2
2
3
3
3
1
I need to select all posts liked by user Arnold (id 1) with all columns from tb_post and number of likes. The result would be something like that:
id
fk_user
title
description
likes
1
2
Movie
I like horror movies
4
3
4
Soccer
The World Cup is coming!
2
I tried this but the number of likes is not correct
SELECT TP.*, COUNT(TPL.fk_post) AS likes
FROM table_post AS TP
RIGHT JOIN table_post_like AS TPL
ON TP.id = TPL.fk_post
WHERE TPL.fk_user = 1
GROUP BY TP.id
Do this
SELECT table_post.*, t.occurence FROM table_post
JOIN
(SELECT fk_post, COUNT(fk_user) as occurence FROM table_post_like WHERE fk_post IN(SELECT fk_post FROM table_post_like WHERE fk_user = 1)
GROUP BY fk_post) as t ON t.fk_post = table_post.id
Query above returns the value as expected
id
fk_user
title
description
likes
1
2
Movie
I like horror movies
4
3
4
Soccer
The World Cup is coming!
2
Check db fiddle here

How to extract repeated values from a database table

Is it possible extract the values of 'score' as shown below when multiple values of passageId are identical for each value of userId.
userId passageId score
1 1 2
1 2 3
1 1 4
1 1 5
2 1 3
2 3 3
2 3 4
Result:
userId passageId scores
1 1 2, 4, 5
1 2 3
2 1 3
2 3 3, 4
I was advised to use the following code, but I need more than two values to be extracted:
SELECT
userId,
passageId,
min(score) as score_1,
max(score) as score_2
FROM mytable
GROUP BY
userId,
passageId
HAVING COUNT(*)>=2;
I was also advised to use string_agg but could not make it work in pgAdmin.
pgadmin suggests that you are using Postgres. That in turn suggests that you should use string_agg() or array_agg():
SELECT userId, passageId, ARRAY_AGG(score)
FROM mytable
GROUP BY userId, passageId
HAVING COUNT(*) >= 2;

SQL Show value that appears more times and how many times

I'm trying to show the value that appears more times from a movies table.
For example:
movie_id, tag_id, score
1 1 4
1 3 5
2 1 3
3 2 4
3 3 5
Result:
tag_id, times
1 2
3 2
2 1
That table has the following columns: {movie-id, tag-id, score}.
How I can retrieve the tag-id that appears more times and how many times?
I've tried the following but it shows the same number for each tag-id:
SELECT tagId, COUNT(tagId) AS ocurrence FROM scores GROUP BY tagId ORDER BY ocurrence DESC
I think you're looking for:
SELECT TAGID, COUNT(TAGID)
FROM TABLENAME
GROUP BY TAGID
ORDER BY COUNT(TAGID)
--or you could do a having clause where COUNT(TAG-ID) > 1
SELECT tagId, COUNT(tagId) FROM scores GROUP BY (tagID) HAVING COUNT(tagId) >= ALL
(SELECT COUNT(tagId) FROM scores GROUP BY (tagId))
This will also work.

Difficult SQL Request?

I have this table tagMusic
id tagid musicid
---------------------
1 1 141
2 4 141
3 3 102
So I need to say:
take me all the music ID who have tag Id 1 AND 4 (for example ).
One way about it is to select only those tags and count how many unique results you got per tag:
SELECT musicid
FROM tagmusic
WHERE tagid IN (1, 4)
GROUP BY musicid
HAVING COUNT(*) = 2