Nel*_*sen 5 sql sybase sap-ase
我需要计算表的行数,但我收到了 count(*) 异常行为的提示。
当我在空表上使用多列选择时,count(*) 不返回结果。但如果我从 select 语句(单列选择)中删除其他列,则会返回预期结果(0 行)。
在下面的代码中,您将找到多个测试来向您展示我在说什么。
下面代码的结构是:
1)创建表
2)空表测试上的多列选择,返回意外结果
3)空表测试单列select,返回预期结果
4)填充表测试上的多列选择,返回预期结果
问题
鉴于这个结果我的问题是:
为什么空表上的多列选择不返回0,而单列选择返回0?
预期结果定义
对我来说预期结果意味着:
如果表为空,count(*) 返回 0。
如果表不为空,则返回行数
--创建测试表
CREATE TABLE #EMPTY_TABLE(
ID INT
)
DECLARE @ID INT
DECLARE @ROWS INT
Run Code Online (Sandbox Code Playgroud)
--空表多列选择
--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
Run Code Online (Sandbox Code Playgroud)
--空表的单列选择
--assignment attempt (Single-column SELECT)
SELECT @ROWS = COUNT(*)
FROM #EMPTY_TABLE
--returns 0 the expected result
SELECT @ROWS Test_03
Run Code Online (Sandbox Code Playgroud)
--带有填充表的多列选择
--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
Run Code Online (Sandbox Code Playgroud)
因此,我阅读了 sybase 的分组机制,并得出结论,在您的查询中,您有一个“Transact-SQL 扩展列”(请参阅:使用情况下的group by 文档-> Transact-SQL 扩展来分组依据和具有):
包含聚合的选择列表可以包含不是聚合函数参数且不包含在 group by 子句中的扩展列。扩展列会影响最终结果的显示,因为会显示额外的行。* (强调我的)
(关于 *:在您的具体情况下,最后一个语句实际上是错误的,因为一行变成零行)
同样在group by 的文档中,在用法 -> 如何进行分组以及使用聚合进行查询时,您会发现:
对于 group by 表达式中的每个唯一值,group by 子句将剩余行收集到一组中。省略 group by 会为整个表创建一个组。 (强调我的)
所以本质上是:
COUNT(*)将触发整个查询成为聚合,因为它是聚合函数(导致隐式GROUP BY NULL)SELECT,然后会将第一组(不包含行)扩展到其包含的行(无),并将其与聚合结果列连接在一起。在您的情况下:计数为 0,因为您还查询了 id,因此对于每个 id 都会生成一行,并在其中附加计数。但是,由于您的表没有行,因此没有任何结果行,因此没有分配。(一些示例位于链接的文档中,并且由于没有 id 并且现有 id 必须位于结果的 id 列中,...)
为了始终获得计数,您可能应该只SELECT @ROWS = COUNT(*)单独选择 id。
| 归档时间: |
|
| 查看次数: |
9212 次 |
| 最近记录: |