简体   繁体   中英

MySQL Group By not working in subquery

I have this query and it works great. I use the MIN(home_price) to display as a starting price and I use this query for an api and WHERE clauses get added to it, so if I search by price the MIN(home_price) changes.

SELECT MIN(home_price) as min_home_price,
   id,
   name,
   community,
   maplocation,
   locationLabel,
   logo 
FROM ourCommunity 
INNER JOIN readyBuilt 
   ON community = home_community 
INNER JOIN rb_locations 
   ON readyBuilt.home_location = rb_locations.locationId 
WHERE id IN ( SELECT DISTINCT id 
                 FROM ourCommunity 
                 INNER JOIN readyBuilt 
                        ON community = home_community 
                 WHERE isDeleted = 0 AND is_upcoming = 0) 
   AND home_status = 1 
 GROUP BY id,name,community,mapLocation,locationLabel,logo 
 ORDER BY name

So my solution was to use a subquery

SELECT id,
   name,
   community,
   maplocation,
   locationLabel,
   logo, 
   (SELECT MIN(home_price) as min_home_price 
          FROM ourCommunity 
          INNER JOIN readyBuilt 
                 ON community = home_community 
          INNER JOIN rb_locations 
                 ON readyBuilt.home_location = rb_locations.locationId 
          WHERE id IN ( SELECT DISTINCT id 
                        FROM ourCommunity 
                        INNER JOIN readyBuilt 
                               ON community = home_community 
                        WHERE isDeleted = 0 
                               AND is_upcoming = 0) 
                 AND home_status = 1 
          GROUP BY id,name,community,mapLocation,locationLabel,logo 
          ORDER BY name) as org_min_home_price 
FROM ourCommunity 
INNER JOIN readyBuilt 
   ON community = home_community 
INNER JOIN rb_locations 
   ON readyBuilt.home_location = rb_locations.locationId 
WHERE id IN ( SELECT DISTINCT id 
                 FROM ourCommunity 
                 INNER JOIN readyBuilt 
                        ON community = home_community 
                 WHERE isDeleted = 0 AND is_upcoming = 0) 
   AND home_status = 1 
 GROUP BY id,name,community,mapLocation,locationLabel,logo 
 ORDER BY name

But when I execute the second query, I get this error

Subquery returns more than 1 row

When I remove the GROUP BY I get no errors by the MIN(home_price) is the same for each row. Does anyone have any suggestion on how to accomplish what I am trying to accomplish?

It's normal that if you add a price as filter the minimum price returned won't be the real minimum of the table.

You could join on a result set of each min(home_price) groupped by community

SELECT min_home_price,   
   id,
   name,
   community,
   maplocation,
   locationLabel,
   logo 
FROM ourCommunity
INNER JOIN (select min(home_price) min_home_price, home_community from readyBuilt group by home_community) b on b.home_community = community
INNER JOIN readyBuilt a ON community = a.home_community 
INNER JOIN rb_locations ON a.home_location = rb_locations.locationId 
WHERE id IN ( SELECT DISTINCT id 
                 FROM ourCommunity 
                 INNER JOIN readyBuilt ON community = home_community 
                 WHERE isDeleted = 0) 
AND home_status = 1 
GROUP BY id,name,community,mapLocation,locationLabel,logo 
ORDER BY name;

Don't use nested subqueries in MySQL for large dataset, otherwise MySQL could end up creating temporary table on its own and query performance will suffer.

I've tried to remove the last nested query as following:

SELECT b.min_home_price,   
oc.id, oc.name, oc.community, oc.maplocation, oc.locationLabel, oc.logo
FROM ourCommunity oc
INNER JOIN (select min(home_price) min_home_price, home_community from readyBuilt group by home_community) b on b.home_community = oc.community
INNER JOIN readyBuilt rb ON oc.community = rb.home_community 
INNER JOIN rb_locations rbl ON rb.home_location = rbl.locationId 
INNER JOIN readyBuilt rb1 ON oc.community = rb1.home_community
WHERE rb1.isDeleted = 0
AND oc.home_status = 1 
 GROUP BY oc.id, oc.name, oc.community, oc.mapLocation, oc.locationLabel, oc.logo 
 ORDER BY oc.name;

If you could please upload your 3 tables definition and the overall objective in plain English, ie WHAT are you trying to achieve rather than starting with HOW you started to solve the problem, may be I could help with simpler query.

In your second query, you only get one row when you don't have the group by because you are selecting min(home_price) for the entire table.

When you add "group by", you are getting a min(home_price) for each id, for each name, for each community, etc.

You need to change the subquery to just get the min(home_price) for the current row of the outer query. Think of the subquery as a function to return the value based on certain parameters (which happen to match the columns in your outer query).

I also suspect that you only need one table in your sub query- the one with the prices. The other tables are probably there to give you the location grouping and so they belong in the outer query. (Try getting the outer query to work without the min price and as that last).

Eg

Select id, name, etc ... , ( select min(price) from p where p.id = oc.id ) as minPrice from our community oc inner join etc ... group by ...

As other answers have shown, there are many ways to achieve that, such as joins instead of subqueries. There are pros and cons for each, unless performance is an issue, just use what is easiest to understand and maintain.

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