2016-04-06 15 views
0

Ich habe eine benutzerdefinierte Funktion udf, die einen Boolean, in MariaDB 5.5 zurückgibt.NICHT IN keine Zeilen zu liefern, unerwartet

Im Folgenden gibt mir, was ich erwarte:

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) 

Ebenso folgende gibt mir die Nummer 12345 (aus der obigen Tabelle nur), so wie ich erwarte:

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; 

würde ich erwarten, dass die folgenden würde ich auch 12345:

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 aber es gibt mir keine Zeilen. Warum?

Antwort

2

Wie in einem Kommentar erwähnt, wenn eine der von der Unterabfrage zurückgegebenen Zeilen NULL ist, dann erhalten Sie keine Zeilen zurück. Eine Lösung ist, für sie zu filtern ausdrücklich:

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

Meine bevorzugte Methode ist not exists zu verwenden, da es die richtige Semantik:

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

Das heißt, eine effizientere Art und Weise ist in der Regel einen Unterschied zu finden in der Reihe, anstatt nach einem count(*) zu suchen. Das heißt, statt alle Zeilen mit demselben Feld bekommen, kann es nicht mehr, wenn es der zweite bekommt:

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

Dank. Und ich wusste das sogar ... nur irgendwie in diesem Fall. +1. – msh210