简体   繁体   中英

MySQL - Referencing outer table value from double nested subquery

The query I really need to execute is follows:

SELECT      u.points
        (SELECT COUNT(1) FROM (SELECT 1 FROM checkin c INNER JOIN wineries w ON w.id = c.winery_id WHERE c.user_id = u.id GROUP BY region_id) b) as states_visited
FROM        users u
GROUP BY u.id
ORDER BY points DESC

However, this causes the following error:

Unknown column 'u.id' in 'where clause'

I've tried with user-defined variables, no errors, but it's not actually referencing the user-defined variable value for some reason:

SELECT      @uid := u.id, u.points
        (SELECT COUNT(1) FROM (SELECT 1 FROM checkin c INNER JOIN wineries w ON w.id = c.winery_id WHERE c.user_id = @uid GROUP BY region_id) b) as states_visited
FROM        users u
GROUP BY u.id
ORDER BY points DESC

Any thoughts how I can make this work? Without the obvious resorting to doing two separate queries?

Why do you need the double nesting? And if the id is the primary key of table user , you don't need the GROUP BY either:

SELECT      u.points,
        (SELECT COUNT(1) FROM reviews WHERE user_id = u.id) AS review_count
FROM        users AS u
-- GROUP BY u.id
ORDER BY points DESC ;

You could also GROUP BY in a derived table - and then join:

SELECT      u.points,
            COALESCE(r.review_count,0) AS review_count
FROM        users AS u
    LEFT JOIN
        (SELECT user_id, COUNT(1) AS review_count
         FROM reviews
         GROUP BY user_id
        ) AS r
        ON  r.user_id = u.id
ORDER BY points DESC ;

or join and then GROUP BY :

SELECT      u.points,
            COUNT(r.user_id) AS review_count
FROM        users AS u
    LEFT JOIN
            reviews AS r
        ON  r.user_id = u.id
GROUP BY u.id, u.points
ORDER BY points DESC ;

The edited version is harder but can be done without double nesting, too:

SELECT      u.points,
        (SELECT COUNT(DISTINCT region_id) 
         FROM checkin c INNER JOIN wineries w ON w.id = c.winery_id 
         WHERE c.user_id = u.id 
        ) AS states_visited
FROM        users u
ORDER BY points DESC ;

It seems like you can do what you want with a simpe table join

SELECT u.id AS `id`, u.points AS `points`, COUNT(r.review_id) AS `review_count` /* or whatever the id record for reviews table is */
FROM users AS u
INNER JOIN reviews AS r
  ON u.id = r.user_id
GROUP BY `id`
ORDER BY `points` DESC
SELECT users.id, users.points, count(*)
FROM users, reviews
WHERE users.id = reviews.user_id
GROUP BY id,points
ORDER BY points DESC

sqlFiddle example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM