Reputation: 360
I have a query
Select
m.name
from machines m
innerJoin config c ON m.cod = c.cod
--> where ( c.category = 'BIOS' and c.val = 'System' )
--> and ( c.category = 'Users' and c.val = 'Jonas' )
group by c.cod
* MACHINES ---------------- +
| key | name | cod |
* ------ + ------- + ------ +
| 1 | M1 | 23 |
| 2 | M2 | 26 |
| 3 | M3 | 27 |
+ ------ + ------- + ------ +
* CONFIG --------------------------- +
| key | category | cod | val |
+ ------ + -------- + ----- + ------ +
| 1 | BIOS | 23 | System |
| 2 | Users | 23 | Jonas |
| 3 | Users | 23 | Maria |
| 4 | BIOS | 26 | System |
| 5 | Users | 26 | Jonas |
| 6 | BIOS | 27 | System |
| 6 | Users | 27 | Ana |
+ ------ + -------- + ----- + ------ +
i got
* RESULT -- +
| name |
+ --------- +
| M1 |
| M2 |
+ --------- +
Its Great for 'Equal' search, but i don't know how i do the 'Not Equal' search for this query.
I tried:
Select
m.name
from machines m
innerJoin config c ON m.cod = c.cod
--> where ( c.category = 'BIOS' and c.val <> 'System' )
--> or ( c.category = 'Users' and c.val <> 'Jonas' )
group by c.cod
but still getting the Machine 'M1', the field with value 'Maria' match with the filter
i need to do with this filter the result:
* RESULT -- +
| name |
+ --------- +
| M3 |
+ --------- +
how can i do it ?
Upvotes: 1
Views: 59
Reputation: 1507
Try this:
SELECT name FROM machines
WHERE name NOT IN (
SELECT m.name FROM machines m INNER JOIN config c ON m.cod = c.cod WHERE ( c.category = 'BIOS' and c.val = 'System' ) AND ( c.category = 'Users' and c.val = 'Jonas' ) GROUP BY c.cod)
Upvotes: 2
Reputation: 35333
Since you need the paired value to have 2 records for the system I'd use this for the equal
This does assume that a category/cod/val is unique in Config.
SELECT m.name
FROM machines m
INNER JOIN config c
on c.cod = m.cod
WHERE (( c.category = 'BIOS' and c.val = 'System' )
OR ( c.category = 'Users' and c.val = 'Jonas' ))
GROUP BY m.name
having count(*) =2 ;
and this for the not equal... note the 2 simply changes if you have a more "OR" critiera
SELECT m.name
FROM machines m
INNER JOIN config c
on c.cod = m.cod
WHERE (( c.category = 'BIOS' and c.val = 'System' )
OR ( c.category = 'Users' and c.val = 'Jonas' ))
GROUP BY m.name
having count(*) <>2 ;
Upvotes: 0
Reputation: 2723
Your posted query has a repeated mistake in it: category
and val
come from table c
, not m
.
Then, it seems to me that what you want is to discard those records which refer to a machine for which other records exist with your condition. Unfortunately, this cannot be done with conditions on records alone, so it’s no use negating conditions. You have to do something like this:
SELECT DISTINCT name
FROM machines
WHERE name NOT IN (
SELECT m.name
FROM machines m
INNER JOIN config c USING (cod)
WHERE ( c.category = 'BIOS' AND c.val = 'System' )
AND ( c.category = 'Users' AND c.val = 'Jonas' )
)
Upvotes: 1
Reputation: 191
Try the following script :
SELECT M.Name FROM Machines AS M LEFT JOIN CONFIG AS C ON M.Cod=C.Cod
WHERE NOT (
(M.Category ='BIOS' AND M.Val='System') AND
(M.Category ='Users' AND M.Val='Jonas')
)
NOT
keyword is easy solution for your query. i also did left join instead inner, you can ignore it if not require.
Upvotes: 0
Reputation: 4620
Select
m.name
from machines m
innerJoin config c ON m.cod = c.cod
where NOT (
( m.category = 'BIOS' and m.val = 'System' )
and ( m.category = 'Users' and m.val = 'Jonas' )
)
group by c.cod
Upvotes: 1