为什么count在空表上不返回0

问题描述 投票:4回答:3

我需要计算一个表的行,但我提示有一个不寻常的count(*)行为。

当我在空表上使用多列选择时,count(*)不返回结果。但是如果我从select语句中删除其他列(单列Select),则返回预期结果(0行)。

在下面的代码中,您将找到多个测试来向您展示我正在谈论的内容。

以下代码的结构是:

1)创建表格

2)空表测试的多列选择,返回意外结果

3)空表测试单列选择,返回预期结果

4)填充表测试的多列选择,返回预期结果

鉴于此结果,我的问题是:

为什么空表上的多列选择不返回0,并且单列选择返回它?

预期结果定义

对我的预期结果意味着:

如果表为空,则count(*)返回0。

如果表不为空,则count返回行计数

- 评估测试表

CREATE TABLE #EMPTY_TABLE(
    ID INT
)

DECLARE @ID INT
DECLARE @ROWS INT

--MULTI COLUMN SELECT WITH EMPTY TABLE

--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

--SLELE COLUMN SELECT EMPTY TABLE

--assignment attempt (Single-column SELECT)
SELECT @ROWS = COUNT(*)
FROM #EMPTY_TABLE

--returns 0 the expected result
SELECT @ROWS Test_03

--MULTI COLUMN SELECT with FILLED TABLE

--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
sql sybase sybase-ase
3个回答
4
投票

所以我阅读了sybase的分组机制,并得出结论,在你的查询中你有一个“Transact-SQL扩展列”(参见:docs on group by下的Usage - > Transact-SQL扩展来分组和拥有):

包含聚合的选择列表可以包括不是聚合函数的参数且不包含在group by子句中的扩展列。扩展列会影响最终结果的显示,因为会显示其他行。*(强调我的)

(关于*:这个最后一个语句在你的具体情况下实际上是错误的,因为一行变成零行)

也可以在docs on group by下使用 - >如何分组和查询聚合工作,你会发现:

group by子句为表中的每个唯一值将剩余的行收集到一个组中。省略组为整个表创建一个组。 (强调我的)

基本上:

  1. 拥有COUNT(*)将触发整个查询成为聚合,因为它是一个聚合函数(导致隐式GROUP BY NULL
  2. SELECT子句中添加ID,然后将第一组(由无行组成)扩展到其包含的行(无)中,并将其与聚合结果列连接在一起。

在你的情况下:计数是0,因为你也查询id,对于每个id,将生成一个附加计数的行。但是,由于您的表没有行,因此没有任何结果行,因此没有分配。 (一些示例在链接的文档中,因为没有id,并且现有的id必须在结果的id列中,...)

总是得到计数,你应该只有SELECT @ROWS = COUNT(*)和分别选择ID。


0
投票

如果你在计算行数并且在没有行时尝试获取ID - 你需要检查它们是否存在。像这样的东西:

SELECT COUNT(*), 
    (CASE WHEN EXISTS(SELECT ID FROM EMPTY_TABLE) THEN (SELECT ID FROM EMPTY_TABLE) ELSE 0 END) AS n_id 
FROM EMPTY_TABLE

如果超过1行,您将收到子查询错误。


0
投票

这个查询:

SELECT @ID = ID, @ROWS = COUNT(*) 
FROM #EMPTY_TABLE

问题是COUNT(*)使这成为一个聚合查询,但你也想返回ID。没有GROUP BY

我怀疑你的最终问题是你忽略了这些错误。

This SQL Fiddle使用SQL Server(类似于Sybase)。但是,失败是非常普遍的,并且由于查询在几乎任何数据库中都不起作用。

© www.soinside.com 2019 - 2024. All rights reserved.