SQLite“;计数(*)";被认为是有害的?

SQLite“;计数(*)";被认为是有害的?,sql,database,sqlite,Sql,Database,Sqlite,考虑以下简单示例: prompt% sqlite3 test.db sqlite> create table employee ( employee_id integer primary key, first_name varchar2(32) not null, last_name varchar2(32) not null ); sqlite> insert in

考虑以下简单示例:

prompt% sqlite3 test.db
sqlite> create table employee (
           employee_id   integer       primary key,
           first_name    varchar2(32)  not null,
           last_name     varchar2(32)  not null
        );

sqlite> insert into employee (first_name, last_name) values ('Bill', 'Smith');
sqlite> insert into employee (first_name, last_name) values ('Sally', 'Jones');
sqlite> insert into employee (first_name, last_name) values ('Bill', 'Jones');

sqlite> select first_name, count(*) from employee;
结果如何

天真的人可能会认为:

Bill|2
Sally|1
但是有经验的人会注意到SELECT查询缺少“GROUPBY”子句。Oracle在提供此查询时,实际上会抛出一个错误:

SQL ERROR: ORA-00937: not a single-group group function
然而,SQLite并没有抱怨,而是产生了:

Bill|3
我觉得这是假的。。。我认为,显示总行数可能有意义,但简单地选择最后一个“first_name”似乎相当武断,而且有潜在的危险

这是一个bug还是一个我无法理解的特性?SQLite没有提供类似的安全网有什么原因吗?

仅此而已:

如果SELECT语句是没有GROUP BY的聚合查询 子句,然后计算结果集中的每个聚合表达式 一旦跨越整个数据集。中的每个非聚合表达式 结果集对任意选择的数据行计算一次 数据集。每一行使用相同的任意选择行 非聚合表达式

通过计算聚合创建的结果集数据的单行 结果集中的非聚合表达式构成 不带GROUPBY子句的聚合查询。不带属性的聚合查询 GROUPBY子句始终只返回一行数据,即使 有零行输入数据


简言之,没有安全网。如果需要,请不要忘记GROUP BY。

如果没有选择所有行,则使用没有
GROUP BY
子句的聚合函数是没有意义的。想想看,你到底在数什么?您需要
按名字从员工组中选择名字、计数(*)
如果所有记录都被视为在一个组中(并且您只需要记录的数量,或者最大值,或者其他任何值),那么使用不带
GROUP BY
的聚合是有意义的。这里没有意义的是
first\u name
的值。这看起来像是一个bug,或者至少是一个非常糟糕的SQL实现。它的实现与MySQL@mwigdahl完全相同。因为,可以使用
MIN
MAX
为非聚合表达式选择行。这是完全不标准的,但在某些情况下很有用。