2016-04-06 26 views
0

MariaDB 5.5'te bir boolean döndüren kullanıcı tanımlı bir işlev udf var. Beklediğim gibi,Hiçbir satır beklenmedik şekilde üretilmiyor NOT

select c, count(*) 
from (
    select fld, count(*)c 
    from tbl 
    where udf(fld) 
    group by fld 
) t 
group by c; 

+---+----------+ 
| c | count(*) | 
+---+----------+ 
| 1 | 12345 | 
| 2 |  1234 | 
| 3 |  123 | 
| 4 |  12 | 
| 5 |  1 | 
+---+----------+ 
5 rows in set (26.75 sec) 

Aynı şekilde, şu bana (sadece yukarıdaki tablodan) numarayı 12345 verir:

select anotherfield, count(*) 
from tbl 
where udf(fld) 
and fld in (
    select fld from (
     select fld,count(*)c 
     from tbl 
     group by fld 
     having c=1 
    )t 
) 
group by anotherfield with rollup; 

isterim

şu beklediğim bana ne verir aşağıdaki da bana 12345 vereceğini bekliyoruz:

select anotherfield, count(*) 
from tbl 
where udf(fld) 
and fld not in (
    select fld from (
     select fld,count(*)c 
     from tbl 
     group by fld 
     having c>1 
    )t 
) 
group by anotherfield with rollup; 

H çünkü, bana hiç satır vermiyor. Niye ya?

cevap

2

Bir yorumda belirtildiği gibi, alt sorgu tarafından döndürülen satırlardan herhangi biri NULL ise, geri satır yok. Bir çözüm açıkça onlar için filtre etmektir:

where fld not in (select fld 
        from tbl 
        where fld is not null 
        group by fld 
        having count(*) > 1 
       ) 

Benim tercih edilen yöntem doğru semantiğini çünkü not exists kullanmaktır: Daha verimli bir şekilde bazı farkı bulmak için genellikle belirterek,

where not exists (select 1 
        from tbl t2 
        group by fld 
        having count(*) > 1 and 
         tbl.fld = t2.fld 
       ) 

Satırda, bir count(*) için denetlemek yerine. ikinci bir aldığında yerine aynı alanla tüm satırları alma,, bu durdurabilir:

where not exists (select 1 
        from tbl t2 
        where tbl.fld = t2.fld and 
         tbl.id <> t2.id -- or some appropriate column 
       ) 
+0

teşekkür ederiz. Ve bunu bile biliyordum ... sadece bir şekilde bu davada kararıyordu. +1. – msh210