Per https://dev.mysql.com/doc/refman/8.0/en/with.html and MySQL "WITH" clause - WITH
is only supported on MySQL 8+. Ensure you're using an appropriate version of MySQL
COnverting to a nested version isn't hard. We take your working sql:
with ratings_by_user as (
select occupation, user_id, count(*) num_ratings
from ratings
group by 1,2
),
max_ratings_by_occupation as (
select occupation, max(num_ratings) as max_ratings
from ratings_by_user
group by 1
),
select occupation, user_id
from ratings_by_user
inner join max_ratings_by_occupation
using (occupation)
where num_ratings = max_ratings
we copy everything including the brackets of the WITH, and paste it in before the use of the alias.
step 1, cut the ratings_by_user and paste it in everwhere the ratings_by_user is used (twice)
--cut from here
with ratings_by_user as ,
max_ratings_by_occupation as (
select occupation, max(num_ratings) as max_ratings
from
--paste to here
(
select occupation, user_id, count(*) num_ratings
from ratings
group by 1,2
) ratings_by_user
group by 1
),
select occupation, user_id
from
--and also paste to here
(
select occupation, user_id, count(*) num_ratings
from ratings
group by 1,2
) ratings_by_user
inner join max_ratings_by_occupation
using (occupation)
where num_ratings = max_ratings
step 2, cut the max_ratings_by_occupation in and paste it in where it's used:
with ratings_by_user as ,
--cut from here
max_ratings_by_occupation as ,
select occupation, user_id
from
(
select occupation, user_id, count(*) num_ratings
from ratings
group by 1,2
) ratings_by_user
inner join
--paste to here
(
select occupation, max(num_ratings) as max_ratings
from
(
select occupation, user_id, count(*) num_ratings
from ratings
group by 1,2
) ratings_by_user
group by 1
) max_ratings_by_occupation
using (occupation)
where num_ratings = max_ratings
step 3, clean up the empty withs
select occupation, user_id
from
(
select occupation, user_id, count(*) num_ratings
from ratings
group by 1,2
) ratings_by_user
inner join
(
select occupation, max(num_ratings) as max_ratings
from
(
select occupation, user_id, count(*) num_ratings
from ratings
group by 1,2
) ratings_by_user
group by 1
) max_ratings_by_occupation
using (occupation)
where num_ratings = max_ratings
This would be a start for optimizing/rewriting. The tricky part for this was that it uses ratings_by_user twice, so two pastes were needed in step 1
Your reformat attempt didn't work out because you were trying to use, at an outer level, a resultset that only existed at an inner level:
select occupation, user_id, count(*) as num_ratings
from
( --max_ratings_table available inside these brackets
select occupation, max(num_ratings) max_ratings
from (
select occupation, user_id, count(*) num_ratings
from users
group by 1,2
) as ratings_table
group by 1
) as max_ratings_table
--end of max_ratings_table availability
)
inner join ratings on ratings.occupation = max_ratings_table.occupation
-- ^^^^^^^^^^^^^^^^^
-- mrt not available here
where max_ratings = num_ratings