I have a result set of parent categories and subcategories. I want to exclude all parent categories if a subcategory exists in the results.
What I would do is using a NOT IN
in the query, but that requires a subquery identical to the main query.
As I’m using match against and possibly other filters in a later stage, I feel there should be an easier way to accomplish this.
The query with the full results is this:
SELECT id,cat_name,cat_parent FROM transport
WHERE MATCH (cat_name) AGAINST ('car*' IN BOOLEAN MODE)
Result:
+-----+------------------+------------+
| id | cat_name | cat_parent |
+-----+------------------+------------+
| 297 | carnaval | 289 |
| 350 | cars & boats | 0 |
| 351 | cars | 350 |
+-----+------------------+------------+
I want to exclude the parent category ‘cars & boats’ as the subcategory ‘cars’ exists in the results.
To accomplish this, I use NOT IN
:
SELECT id,cat_name,cat_parent FROM transport
WHERE MATCH (cat_name) AGAINST ('car*' IN BOOLEAN MODE)
AND id NOT IN(
SELECT cat_parent FROM transport
WHERE MATCH (cat_name) AGAINST ('car*' IN BOOLEAN mode)
)
This works great, but I don’t like it that I have to copy the query in the NOT IN. It feels redundant, even though all the answers to similar questions on SO lead to the same answer, using a subquery with either NOT IN or NOT EXISTS.
I have tried AND id != cat_parent
and AND id NOT IN (cat_parent)
, but that just results in the same output.
Is there any way to accomplish this by just using the result set?
2
Answers
You can try a query like this:
If you only want to "write" the WHERE clause once so that you don’t have to do it twice and keep it the same, you can achieve this with CTE. e.g. like this:
If your sample is representative can’t you just count by parent filtering on car
https://dbfiddle.uk/sgU0RFip