Reputation: 11841
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?
Upvotes: 5
Views: 3315
Reputation: 69
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).
E.g
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.
Upvotes: 0
Reputation: 21004
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;
Upvotes: 6
Reputation: 2660
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, i.e. 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.
Upvotes: 0