Sql 为什么计数在空表上不返回0
我需要计算一个表的行数,但有一个异常的count*行为提示我 在空表上使用多列选择时,count*不返回结果。但是如果我从select语句单列select中删除其他列,则返回预期结果0行 在下面的代码中,您将发现多个测试向您展示我所说的内容 以下代码的结构为: 1表的创建 2个多列选择空表测试,返回意外结果 3单列选择空表测试,返回预期结果 4多列选择填充表测试,返回预期结果 问题: 鉴于这一结果,我的问题是: 为什么空表上的多列select不返回0,而单列select返回0 预期成果定义 对我来说,预期结果意味着: 如果表为空,count*返回0 如果表不是空的,count返回行计数 -创建测试表 -空表多列选择 -单列选择,表为空 -带填充表的多列选择Sql 为什么计数在空表上不返回0,sql,sybase,sap-ase,Sql,Sybase,Sap Ase,我需要计算一个表的行数,但有一个异常的count*行为提示我 在空表上使用多列选择时,count*不返回结果。但是如果我从select语句单列select中删除其他列,则返回预期结果0行 在下面的代码中,您将发现多个测试向您展示我所说的内容 以下代码的结构为: 1表的创建 2个多列选择空表测试,返回意外结果 3单列选择空表测试,返回预期结果 4多列选择填充表测试,返回预期结果 问题: 鉴于这一结果,我的问题是: 为什么空表上的多列select不返回0,而单列select返回0 预期成果定义 对我
因此,我阅读了sybase的分组机制,并得出结论,在您的查询中有一个Transact-SQL扩展列,请参见:在用法->Transact-SQL extensions to group by下,并具有: 包含聚合的select列表可以包含不是聚合函数参数且不包含在group by子句中的扩展列。扩展列会影响最终结果的显示,因为会显示更多的行。*emphasis mine 关于*:在您的特定情况下,最后一个语句实际上是错误的,因为一行变成了零行 此外,在正在使用的->分组方式和使用聚合进行查询时,您会发现: GROUPBY子句将GROUPBY表达式中每个唯一值的剩余行收集到一个组中。忽略group by将为整个表创建一个组。重点矿山 因此,本质上: 拥有COUNT*将触发整个查询成为聚合,因为它是一个聚合函数,导致一个隐式GROUP BY NULL 在SELECT子句中添加ID,然后将第一个不包含任何行的组扩展到其包含的行none中,并将其与聚合结果列连接在一起。 在您的例子中:计数是0,因为您也查询id,所以对于每个id,都将生成一行,并将计数附加到该行。但是,由于您的表没有行,因此没有结果行,因此没有赋值。链接文档中有一些示例,由于没有id,并且结果的id列中必须包含现有id
要始终获取计数,您可能只需要选择@ROWS=count*并分别选择ID。如果您正在计算行数并试图在没有行的情况下获取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行,则会出现子查询错误。此查询:
SELECT @ID = ID, @ROWS = COUNT(*)
FROM #EMPTY_TABLE
问题是COUNT*使其成为聚合查询,但您还希望返回ID。没有分组依据
我怀疑你的最终问题是你忽略了这些错误
sqlfiddle使用类似于Sybase的sqlserver。但是,失败是相当普遍的,并且是由于查询在几乎任何数据库中都不起作用。只是一个想法:如果表中至少有一行,则从空\u表中选择ID将只返回结果行,但是,从空\u表中选择计数*隐式group by应返回结果行,即使没有表行。在假设这是sybase中的有效查询的情况下,我会假设这两个查询的结果被合并以回答您的查询,因为第一个查询不生成行,所以组合查询也不会生成结果,因此没有赋值。但是免责声明:我对sybase没有任何经验。感谢您输入Jakumi。我实际上不知道这种行为是否也发生在其他数据库中,如mysql或sqlserver。但根据我的理解,count*应该返回结果,即使没有行。在某些情况下,这不适用于按特定案例分组的情况,但这不是有趣的案例。因此,Sybase允许GROUPBY中不包含非聚合列。顺便说一句,在MSSQLServer的T-Sql中也有同样的效果。测验除非需要GROUP BY。显式GROUP BY仅指定要用于聚合的组,默认值为属于一个组的所有行,需要显式GROUP BY通常只是为了在可能存在多个未分组列的值时正确定义列。额外测试:向该表添加另一个ID。我希望结果是两个记录,每个记录的计数为1,甚至是组
结果是一样的。你是对的,他忽略了错误。嗨,戈登·林诺夫,我怀疑这是一种普遍的行为,但还没有测试过。这就是为什么我真的想了解这种行为。我忽略了哪些错误?如果没有显示错误?如果错误不存在,我不能忽略它。我可能忽略的是一些行为,而不是错误,因为在我所介绍的案例中它们都不是。嗨@M.N.,我不相信这能回答问题question@Nelssen,如果没有要返回的内容-查询将返回。。。没有不为空的。COUNT and EXISTS返回的不是表中的原始数据,如果没有数据,则使用COUNT 0,并且存在您需要的所有数据。只需像这样尝试smth:从ID=999[无]的空表中选择ID/100 AS。然后从ID=999[NULL]的空_表中选择100/选择g1。因此,在您的情况下,查询需要返回一些内容,如果您想将其与count一起使用。您好,M.N.,感谢您的努力,这不是我们为什么需要进行此解决方法的答案。此解决方案仅适用于非常特定的情况,即0行和1行。如果它在所有场景0、1或许多行中都有效,我会投票支持它,但不能像现在这样做。下次一定要提供更可持续的解决方案:Great Search@Jakumi,不幸的是,这个具体的例子没有显示在链接中,但它们给出了在这个具体情况下可能发生什么的非常好的想法。阅读后,我得出结论:创建组时没有行,并且由于组被扩展,它将与没有行的表连接,并且将空表与另一个表内部连接的结果是空表。感谢您提供的参考链接。@Nelssen-从错误的参数中得出正确的结论;-。可以说,你的问题与加入无关,而是与分组有关。正如Jakumi所写:计数没有分组,因此根据定义,无法显示任何内容。这就是它的工作原理。您是正确的,这可能是由于连接到空表引起的,但即使没有任何内容,COUNT也会返回一些内容,除非混合中有GROUP by。
--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 COUNT(*),
(CASE WHEN EXISTS(SELECT ID FROM EMPTY_TABLE) THEN (SELECT ID FROM EMPTY_TABLE) ELSE 0 END) AS n_id
FROM EMPTY_TABLE
SELECT @ID = ID, @ROWS = COUNT(*)
FROM #EMPTY_TABLE