I have this table of data:
+-----+-----------+------------------------------------+---------+
| ID | post_type | name | term_id |
+-----+-----------+------------------------------------+---------+
| 278 | supplier | Heating | 15 |
| 282 | supplier | Central Heating | 16 |
| 278 | supplier | Biomass | 17 |
| 278 | supplier | Ground Source Heat Pumps | 18 |
| 278 | supplier | Passive Solar | 19 |
| 282 | supplier | Air Source Heat Pumps | 21 |
| 278 | supplier | Air Conditioning | 22 |
| 278 | supplier | Boilers | 23 |
| 277 | supplier | Lighting | 25 |
| 277 | supplier | LED's | 26 |
| 282 | supplier | Halogen | 28 |
| 277 | supplier | CFL | 29 |
| 282 | supplier | Sustainable Construction Materials | 31 |
| 282 | supplier | Plaster | 33 |
| 282 | supplier | Floors | 37 |
| 282 | supplier | Water | 38 |
| 282 | supplier | Showers & Baths | 43 |
| 278 | supplier | Cooling | 44 |
| 278 | supplier | Refrigeration | 46 |
| 282 | supplier | Passive Design | 47 |
| 278 | supplier | Chillers | 48 |
| 282 | supplier | Renewable Energy | 49 |
| 282 | supplier | Air Source Heat Pumps | 53 |
| 282 | supplier | Biomass Heating | 55 |
| 282 | supplier | Biofuels | 57 |
| 282 | supplier | Insulation | 61 |
| 282 | supplier | Wall | 63 |
| 282 | supplier | Floor | 64 |
| 282 | supplier | Draught Proofing | 65 |
| 282 | supplier | Energy Efficiency | 70 |
| 282 | supplier | Gas Boiler Management Systems | 71 |
| 282 | supplier | Low Energy Lighting | 72 |
| 282 | supplier | Voltage Control | 73 |
| 282 | supplier | Smart Meters | 74 |
| 282 | supplier | Electric Heating | 75 |
+-----+-----------+------------------------------------+---------+
And need to extract a list of IDs that apply to BOTH a specified name (wildcard string) and a term_id (integer). So for example I’d search for the IDs that have a name LIKE '%Lighting%' and a term_id = 26…which should return ID 277.
The following query works but isn’t pretty:
SELECT a.ID, d.name, d.term_id
FROM cn_posts AS a
INNER JOIN cn_postmeta AS b ON a.ID = b.post_id
INNER JOIN cn_term_relationships AS c ON a.ID = c.object_id
INNER JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
WHERE a.post_status = 'publish'
AND d.name LIKE '%Lighting%'
AND a.ID IN (
SELECT a.ID
FROM cn_posts AS a
INNER JOIN cn_postmeta AS b ON a.ID = b.post_id
INNER JOIN cn_term_relationships AS c ON a.ID = c.object_id
INNER JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
WHERE d.term_id = '26'
)
GROUP BY a.ID
I’ve tried the following queries but they all return no results:
SELECT DISTINCT a.ID, d.name, d.term_id
FROM cn_posts AS a
LEFT JOIN cn_postmeta AS b ON a.ID = b.post_id
LEFT JOIN cn_term_relationships AS c ON a.ID = c.object_id
LEFT JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
WHERE a.post_status = 'publish'
AND d.name LIKE '%Lighting%'
AND d.term_id = '26'
SELECT a.ID, d.name, d.term_id, a.post_status
FROM cn_posts AS a
JOIN cn_postmeta AS b ON a.ID = b.post_id
JOIN cn_term_relationships AS c ON a.ID = c.object_id
JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
WHERE a.post_status = 'publish'
AND d.name LIKE '%Lighting%'
AND d.term_id = '26'
GROUP BY a.ID
These both return posts:
SELECT a.ID, d.name, d.term_id, a.post_status
FROM cn_posts AS a
JOIN cn_postmeta AS b ON a.ID = b.post_id
JOIN cn_term_relationships AS c ON a.ID = c.object_id
JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
WHERE a.post_status = 'publish'
AND d.name LIKE '%Lighting%'
SELECT a.ID, d.name, d.term_id, a.post_status
FROM cn_posts AS a
JOIN cn_postmeta AS b ON a.ID = b.post_id
JOIN cn_term_relationships AS c ON a.ID = c.object_id
JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
WHERE a.post_status = 'publish'
AND d.term_id = '26'
But when you include both the name and term_id in the query it returns nothing?
Obviously, no single row in the table (your data sample) matches the condition of
d.name LIKE '%Lighting%' AND d.term_id = '26'. There are rows matching the first part and those matching the second part, but none matching both. However, if taken as a group of rows, theID = 277does match the condition. Therefore, you need to introduce grouping and apply the condition, albeit slightly modified, in the HAVING clause, like this:Note, however, that this means you can’t obtain the details like
d.nameord.termalongside the IDs in the same query (but pulling other columns fromawould be all right in this case). If returning thedcolumns in the same query is mandatory to solving your problem, you’d likely need to use the above as a derived table in an almost identical query that pulls all the data you need. The derived table would in that case be used as a means of filtering down the set of IDs to just those matching both conditions. And in that main query, the two conditions would need to be connected withORrather than withAND, like this:Apparently, this would hardly be better than the query you’ve ended up.