Jump to content

Is there a mysql bit similar to IN(), but something more like "IN ALL()"?


ultrus

Recommended Posts

I'm attempting to retrieve a list of solar systems in the fictitious EVE Online galaxy that contain ALL of the requested types of ice. Fun aye? I'm having brain shortage on the proper structure for this. :P

 

Getting systems for one type of ice is pretty straight forward:

 

SELECT s.solarSystemID
FROM mapRegionIceTypes i
LEFT JOIN invTypes t ON i.typeID = t.typeID
LEFT JOIN mapSolarSystems s ON s.regionID = i.regionID
WHERE  i.maxSecurity >= s.security 
AND i.minSecurity <= s.security 
AND i.typeID = 17976

 

This one makes sense for systems containing ANY of the requested ice (not quite what I need)

 

SELECT s.solarSystemID
FROM mapRegionIceTypes i
LEFT JOIN invTypes t ON i.typeID = t.typeID
LEFT JOIN mapSolarSystems s ON s.regionID = i.regionID
WHERE  i.maxSecurity >= s.security 
AND i.minSecurity <= s.security 
AND i.typeID IN (16264,16262,16267)

 

How would I select systems with ALL of the requested types of ice?

 

Thanks for your feedback in advance. Let me know if I can provide further info.

Link to comment
Share on other sites

The cleanest way (for an arbitrary number of 'having all x' present) is to use IN() the way you are currently, but GROUP BY s.solarSystemID and then get a count of how many are in each group, and add a HAVING count = 3.

 

Untested but should work -

 

SELECT s.solarSystemID, count(*) as cnt
FROM mapRegionIceTypes i
LEFT JOIN invTypes t ON i.typeID = t.typeID
LEFT JOIN mapSolarSystems s ON s.regionID = i.regionID
WHERE  i.maxSecurity >= s.security
AND i.minSecurity <= s.security
AND i.typeID IN (16264,16262,16267)
GROUP BY s.solarSystemID
HAVING cnt = 3

 

The HAVING cnt = x would need to match the number of different choices being used in the IN() term.

Link to comment
Share on other sites

PFMaBiSmAd,

I was just about to post a similar solution but it was semi-broke without the "HAVING" part:

SELECT s.solarSystemID, COUNT(i.typeID) AS count
FROM mapRegionIceTypes i
LEFT JOIN invTypes t ON i.typeID=t.typeID
LEFT JOIN mapSolarSystems s ON s.regionID=i.regionID
WHERE  i.maxSecurity >= s.security 
AND i.minSecurity <= s.security 
AND i.typeID IN (16266,16267)
GROUP BY s.solarSystemID
ORDER BY count DESC

 

Here's the fixed one based on your advise:

 

SELECT s.solarSystemID, COUNT(i.typeID) AS count
FROM mapRegionIceTypes i
LEFT JOIN invTypes t ON i.typeID=t.typeID
LEFT JOIN mapSolarSystems s ON s.regionID=i.regionID
WHERE  i.maxSecurity >= s.security 
AND i.minSecurity <= s.security 
AND i.typeID IN (16266,16267)
GROUP BY s.solarSystemID
HAVING count = 2

 

Awesome! Thank you super much. :D

 

Fenway,

Thanks for your feedback as well. Since the database is somewhat small and won't grow much, the above works fine. Otherwise, there could be up to 12 joins. I don't know what the performance difference would be at this time.

 

Best regards,

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.