Reputation: 3
I have a table with two columns. One Column is the Material number and the other one is the Language. Some Material numbers have multiple Languages and I would like to only get those that do not have a 'DE' or 'EN' entry. So basically as soon as a material number has a 'DE' or 'EN' in the lang field it should not be displayed.
This is the Query that I tried using:
select * from table where matnr not in (select matnr from table where lang = "DE" or lang = "EN")
However the Data I am trying to analyze has over a million entries which takes really really long.
The weird thing is that I even
select top 1 * from table where matnr not in (select matnr from table where lang = "DE" or lang = "EN")
seems to take a really long time.
Am I doing something wrong here? Does anyone have an idea how I could achieve the same thing in a way that is more performant?
Thank you for your help!
Upvotes: 0
Views: 41
Reputation: 16015
You could try using a left join
coupled with a where is null
clause, e.g.:
select top 1 t1.*
from
table t1 left join
(
select distinct t2.matnr
from table t2 where t2.lang = 'DE' or t2.lang = 'EN'
)
on t1.matnr = t2.matnr
where
t2.matnr is null
Upvotes: 0
Reputation: 1270483
One method is not exists
with an index on (matnr, lang)
:
select t.*
from table as t
where not exists (select 1
from table as t2
where t2.matnr = t.matnr AND
t2.lang = "DE"
) and
not exists (select 1
from table as t2
where t2.matnr = t.matnr AND
t2.lang = "EN"
) ;
Another would use aggregation and INNER JOIN
:
select t.*
from table as t inner join
(select t2.matnr
from table as t2
group by t2.matnr
having sum(iff(lang in ("DE", "EN"), 1, 0)) = 0
) as t2
on t.matnr = t2.matnr;
Upvotes: 1