【发布时间】:2019-08-05 03:33:47
【问题描述】:
我需要计算一个表的行数,但我收到了 count(*) 异常行为的提示。
count(*) 在空表上使用多列选择时不返回结果。但如果我从 select 语句中删除其他列(单列选择),则会返回预期结果(0 行)。
在下面的代码中,您会发现多个测试来向您展示我在说什么。
下面的代码结构为:
1) 创建表
2) 空表测试多列选择,返回意外结果
3) 空表测试单列选择,返回预期结果
4) 填表测试多列选择,返回预期结果
问题
鉴于此结果,我的问题是:
为什么空表的多列选择不返回0,而单列选择返回呢?
预期结果定义
对我来说预期的结果意味着:
如果表为空,count(*) 返回 0。
如果表不为空,count 返回行数
--创建测试表
CREATE TABLE #EMPTY_TABLE(
ID INT
)
DECLARE @ID INT
DECLARE @ROWS INT
--空表多列选择
--assignment attempt (Multi-column SELECT)
SELECT @ID = ID, @ROWS = COUNT(*)
FROM #EMPTY_TABLE
--return Null instead of 0
SELECT @ROWS Test_01 , ISNULL(@ROWS, 1 )'IS NULL'
--Set variable with random value, just to show that not even the assignment is happening
SET @ROWS = 29
--assignment attempt (Multi-column SELECT)
SELECT @ID = ID, @ROWS = COUNT(*)
FROM #EMPTY_TABLE
--return 29 instead of 0
SELECT @ROWS Test_02
--带空表的单列选择
--assignment attempt (Single-column SELECT)
SELECT @ROWS = COUNT(*)
FROM #EMPTY_TABLE
--returns 0 the expected result
SELECT @ROWS Test_03
--带填充表的多列选择
--insert a row
INSERT INTO #EMPTY_TABLE(ID)
SELECT 1
--assignment attempt
SELECT @ID = ID, @ROWS = COUNT(*)
FROM #EMPTY_TABLE
--Returns 1
SELECT @ROWS Test_04
【问题讨论】:
-
只是一个想法:
select ID from #empty_table只会返回一个结果行,如果表至少有一行,但是,select count(*) from #empty_table(隐式分组依据)应该返回一个结果行,即使有没有表格行。假设这是 sybase 中的有效查询,我假设这两个查询的结果被连接以回答您的查询,因为第一个查询不产生任何行,组合查询也不会产生任何结果,因此没有分配。但是...免责声明:我对 sybase 没有任何经验。 -
感谢您输入 Jakumi。我实际上不知道这种行为是否也发生在其他数据库中,如 mysql 或 sqlserver。但根据我的理解,即使没有行,count(*) 也应该返回结果。在某些情况下这不适用,即在使用 group by 时(特定情况),但情况并非如此
-
有趣。因此 Sybase 允许非聚合列不包含在 group by 中。顺便说一句,MS Sql Server 的 T-Sql 中也有同样的效果。测试here。除非这时需要 GROUP BY。
-
显式 GROUP BY 只指定用于聚合的组,默认是属于一个组的所有行,需要显式 group by 通常只是为了在有多个未分组值时正确定义列列(可能)。
-
额外测试:向该表添加另一个 ID。我希望结果是两条记录,每条记录为 1