Mysql 意外地,不在不产生行中

Mysql 意外地,不在不产生行中,mysql,mariadb,having,mysql-5.5,notin,Mysql,Mariadb,Having,Mysql 5.5,Notin,在MariaDB 5.5中,我有一个用户定义的函数udf,它返回一个布尔值 以下是我的期望: 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 |

在MariaDB 5.5中,我有一个用户定义的函数udf,它返回一个布尔值

以下是我的期望:

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)
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;
同样,正如我预期的那样,下面给出了上表中的数字12345:

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)
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;
我希望以下内容也能为我提供12345:


然而,它并没有给我带来任何麻烦。为什么?

如注释中所述,如果子查询返回的任何行为空,则不会返回任何行。一种解决方案是显式筛选它们:

where fld not in (select fld 
                  from tbl
                  where fld is not null
                  group by fld
                  having count(*) > 1 
                )
我首选的方法是使用not exists,因为它具有正确的语义:

where not exists (select 1 
                  from tbl t2
                  group by fld
                  having count(*) > 1 and
                         tbl.fld = t2.fld
                 )
也就是说,更有效的方法通常是在行中找到一些差异,而不是检查计数*。也就是说,它可以在获取第二个字段时停止,而不是获取具有相同字段的所有行:

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

如注释中所述,如果子查询返回的任何行为NULL,则不会返回任何行。一种解决方案是显式筛选它们:

where fld not in (select fld 
                  from tbl
                  where fld is not null
                  group by fld
                  having count(*) > 1 
                )
我首选的方法是使用not exists,因为它具有正确的语义:

where not exists (select 1 
                  from tbl t2
                  group by fld
                  having count(*) > 1 and
                         tbl.fld = t2.fld
                 )
也就是说,更有效的方法通常是在行中找到一些差异,而不是检查计数*。也就是说,它可以在获取第二个字段时停止,而不是获取具有相同字段的所有行:

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

谢谢我甚至知道。。。在这种情况下,不知怎么的就把它盖上了+1.谢谢。我甚至知道。。。在这种情况下,不知怎么的就把它盖上了+1.