Reputation: 21
I have the following table:
Tablename: yay
id | tagname | value
----+---------+---------
0 | Farbe | Gelb
0 | Preis | 1.15
0 | Thema | Herbst
1 | Farbe | Maigrün
1 | Preis | 1.15
1 | Thema | Herbst
2 | Farbe | Schwarz
2 | Preis | 1.15
2 | Thema | Sommer
What i want is to get all rows of an id for which one or more conditions are satisfied and one or more where not.
If, for example, i want all id
with their rows in the table where tagname='Preis'
, value='1.15'
and tagname=Thema
, value='Herbst'
is satisfied, but don't want id
where tagname='Farbe'
, value='Schwarz'
becomes true. The result should look like this:
id | tagname | value
----+---------+---------
0 | Farbe | Gelb
0 | Preis | 1.15
0 | Thema | Herbst
1 | Farbe | Maigrün
1 | Preis | 1.15
1 | Thema | Herbst
When at least one condition for inclusion is met, all rows containing the id
where the condition was met are to be in the result.
But if at least one condition for the exclusion is met, then no row of the corresponding id
shall be in the result.
Upvotes: 1
Views: 1589
Reputation: 1271051
If you just want the id
s, you can do:
select id
from yay
group by id
having sum(case when tagname = 'preis' and value = '1.15' then 1 else 0 end) > 0 and
sum(case when tagname = 'Thema' and value = 'Herbst' then 1 else 0 end) > 0 and
sum(case when tagname = 'Farbe' and value = 'Schwarz' then 1 else 0 end) = 0;
Each condition counts the number of matching rows. The first two require at least one match (each) for an id
, because of the > 0
. The third says there are no match, because of the = 0
.
You can get the original data by joining back:
select yay.*
from yay join
(select id
from yay
group by id
having sum(case when tagname = 'preis' and value = '1.15' then 1 else 0 end) > 0 and
sum(case when tagname = 'Thema' and value = 'Herbst' then 1 else 0 end) > 0 and
sum(case when tagname = 'Farbe' and value = 'Schwarz' then 1 else 0 end) = 0
) yid
on yay.id = yid.id;
Upvotes: 3