2013-04-02 56 views
2

考虑下面简单的例子:SQLite“COUNT(*)”被认为是有害的?

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查询缺少“GROUP BY子句。甲骨文,当此查询提出将,其实,扔了一个错误:

SQL ERROR: ORA-00937: not a single-group group function 

SQLite的,但是,不抱怨,而是产生:

Bill|3 

这似乎假我。 ..我想,显示行的总数可能是有意义的,但只要选择最后一个'first_name'似乎是任意的和潜在的危险。

这是一个错误或功能,我只是不明白? SQLite不提供类似的安全网有什么原因吗?

+0

当您没有选择所有行时,使用没有“GROUP BY”子句的聚合函数是没有意义的。想想,你甚至还在计算什么?你希望从first_name中选择雇员组的first_name,count(*);' – NullUserException

+0

如果所有记录都被认为是在一个组中,那么使用一个没有“GROUP BY”的聚合是有意义的(并且你想要的只是记录数量或最大价值等等)。这里没有意义的是'first_name'的值。这看起来像一个错误,或者至少是一个极其糟糕的SQL实现。 – mwigdahl

+0

这对MySQL @mwigdahl是一个相同的实现。 – Ben

回答

5

这是所有documented

If the SELECT statement is an aggregate query without a GROUP BY clause, then each aggregate expression in the result-set is evaluated once across the entire dataset. Each non-aggregate expression in the result-set is evaluated once for an arbitrarily selected row of the dataset. The same arbitrarily selected row is used for each non-aggregate expression...

The single row of result-set data created by evaluating the aggregate and non-aggregate expressions in the result-set forms the result of an aggregate query without a GROUP BY clause. An aggregate query without a GROUP BY clause always returns exactly one row of data, even if there are zero rows of input data.

简单地说,有没有安全网。如果您需要,请不要忘记GROUP BY。

+1

从[SQLite 3.7.11](http://www.sqlite.org/releaselog/3_7_11.html)开始,可以选择具有“MIN”或“MAX”的非聚合表达式的行。这完全是非标准的,但在某些情况下很有用。 –

相关问题