如何高效地检查一个表是否为空?

34

我正在编写的程序中,有一个地方需要检查表格是否为空。我目前只有一个基本的SQL执行语句:

Count(asterisk) from Table
我有一个获取数据行的方法,将 Count(asterisk) 放入参数中以便进行检查(如果 count(*) < 1,则出现错误,因为这意味着该表为空)。平均而言,count(asterisk) 会返回大约 11,000 行。这种做法是否更有效?
 select count(*) 
 from (select top 1 * 
        from TABLE)

但是我无法在Microsoft SQL Server中使其工作。

这将返回1或0,当执行语句并获取计数参数以查看TABLE是否为空时,我将能够在编程语言中检查该参数。

欢迎任何评论、想法或关注。


6
SQL Server 提供了许多工具来评估查询性能(执行计划、DMV 和 DMO、Profiler 追踪等),因此您不应该问“这样做是否更有效率”。通过使用代表生产环境的数据,尝试以多种方式运行查询,并选择产生最佳结果的一种方法。请注意,您可以从自己的环境中得出确切的答案。 - alroc
我对Microsoft SQL Server非常陌生,也不熟悉这些工具。我会进一步了解你提到的工具。感谢帮助。 - Colin Douglas
7个回答

58

如果您想判断表是否为空,可以使用SQL的EXISTS关键字。如果您是在存储过程中执行此操作,请使用以下模式:

IF(NOT EXISTS(SELECT 1 FROM dbo.MyTable))
BEGIN
  RAISERROR('MyError',16,10);
END;

如果您希望在应用程序内根据指示器的反馈采取相应措施,请使用以下模式:

SELECT CASE WHEN EXISTS(SELECT 1 FROM dbo.MyTable) THEN 0 ELSE 1 END AS IsEmpty;

虽然其他回答也能产生所需的结果,但它们似乎掩盖了意图。


1
括号 - () - 在 NOT Exists ... 周围不是必需的。这是检查表中是否存在行的正确工具。 - Stoleg
5
@Stoleg,你是正确的,()不是必须的。这只是一个模式,我采用了它来将IF条件始终包装在()中,因为大多数其他语言都需要这样做。 - Sebastian Meine
在你的exists语句中加入TOP 1是一个很好的做法。在非常大的表中,你将返回每一条记录。 - undefined
1
这是不正确的,@KeyOfJ。无论是否存在TOP子句,SQL Server都会在找到第一行时停止执行EXISTS查询。 - undefined
1
@SebastianMeine 谢谢,我一直以为这就是为什么我们被教导要添加 TOP 1。“EXISTS 运算符在找到一行后立即终止查询处理,因此,您可以利用 EXISTS 运算符的这个特性来提高查询性能。” - undefined

12
你可以尝试这样做:

您可以尝试类似以下内容:

select count(1) where exists (select * from t)

SQLFiddle上进行了测试。


4
我很喜欢这种方法,因为它使用标准 SQL。 - Gordon Linoff
@Stoleg 因为要求是选择1或0,而如果表为空,则 select 1 将不返回任何行。 - mustaccio
@mustaccio,非常抱歉!它确实有用! - Stoleg

8
请在检查是否存在时使用top 1,否则您将获得与记录数量相同的“一”:
IF NOT EXISTS(select top 1 1 from Table)
BEGIN
  RAISERROR('Error',0,1);
END;

3

看起来这个方法有些奇怪,你能不能直接使用HAVING呢?

SELECT id, name FROM TABLE
GROUP BY id, name
HAVING COUNT(*) > 0

3

我想写关于EXISTS,但Sebastian Meine更快地完成了。虽然我更喜欢使用EXISTS,但还有一种方法。

SELECT rows 
FROM sys.partitions 
WHERE object_id = object_id('MyTableName') 
    AND partition_number = 1

2

IF EXISTS 可用于检查表是否为空。

IF EXISTS (select * from YourTable)
SELECT 'Table is not empty'
ELSE
SELECT 'Table is empty'

2

您的变量是正确的。您只需要在子查询上添加一个别名:

 select count(*) 
 from (select top 1 * 
        from TABLE
      ) t

谢谢Gordon。我通常在MS Access中编写查询,不知道我必须在子查询上创建别名,因此这非常有帮助。 - Colin Douglas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接