当前位置:  开发笔记 > 数据库 > 正文

SELECT语句后需要行计数:什么是最佳SQL方法?

如何解决《SELECT语句后需要行计数:什么是最佳SQL方法?》经验,为你挑选了2个好方法。

我正在尝试从单个表中选择一个列(没有连接),我需要计算行数,理想情况是在开始检索行之前.我已经提出了两种方法来提供我需要的信息.

方法1:

SELECT COUNT( my_table.my_col ) AS row_count
  FROM my_table
 WHERE my_table.foo = 'bar'

然后

SELECT my_table.my_col
  FROM my_table
 WHERE my_table.foo = 'bar'

方法2

SELECT my_table.my_col, ( SELECT COUNT ( my_table.my_col )
                            FROM my_table
                           WHERE my_table.foo = 'bar' ) AS row_count
  FROM my_table
 WHERE my_table.foo = 'bar'

我这样做是因为我的SQL驱动程序(SQL Native Client 9.0)不允许我在SELECT语句中使用SQLRowCount,但我需要知道结果中的行数,以便在为其分配数据之前分配数组.遗憾的是,在我的程序的这个方面,使用动态分配的容器不是一个选项.

我担心可能会出现以下情况:

发生SELECT计数

发生另一条指令,添加或删除一行

发生数据SELECT,突然数组的大小错误.
- 在更糟糕的情况下,这将尝试写入超出数组限制的数据并使我的程序崩溃.

方法2是否禁止此问题?

此外,两种方法中的一种会更快吗?如果是这样,哪个?

最后,是否有一个更好的方法我应该考虑(也许是一种方法来指示驱动程序使用SQLRowCount返回SELECT结果中的行数?)

对于那些问的人,我使用的是Native C++和上面提到的SQL驱动程序(由Microsoft提供).



1> Adam Porad..:

如果您正在使用SQL Server,则在查询之后可以选择@@ RowCount函数(或者如果您的结果集可能有超过20亿行使用BIGROW_COUNT()函数).这将返回前一个语句选择的行数或受insert/update/delete语句影响的行数.

SELECT my_table.my_col
  FROM my_table
 WHERE my_table.foo = 'bar'

SELECT @@Rowcount

或者,如果要将结果中包含的行计数类似于方法#2,则可以使用OVER子句(请参阅http://msdn.microsoft.com/en-us/library/ms189461.aspx 1).

SELECT my_table.my_col,
    count(*) OVER(PARTITION BY my_table.foo) AS 'Count'
  FROM my_table
 WHERE my_table.foo = 'bar'

使用OVER子句比使用子查询获得行计数要好得多.使用@@ RowCount将获得最佳性能,因为select @@ RowCount语句不会有任何查询成本

更新以回应评论:我给出的示例将给出分区中的行数 - 在本例中由"PARTITION BY my_table.foo"定义.每行中列的值是具有相同my_table.foo值的行数.由于您的示例查询具有子句"WHERE my_table.foo ='bar'",因此结果集中的所有行将具有相同的my_table.foo值,因此列中的值对于所有行都相同且相等(在这种情况)这是查询中的行数.

下面是一个更好/更简单的示例,说明如何在每一行中包含一列,即结果集中的总行数.只需删除可选的Partition By子句即可.

SELECT my_table.my_col, count(*) OVER() AS 'Count'
  FROM my_table
 WHERE my_table.foo = 'bar'


count(*)OVER()AS'Count'为我工作.

2> Bill Karwin..:

只有两种方法可以100%确定COUNT(*)实际查询会产生一致的结果:

结合COUNT(*)查询,如您的方法2.我建议您在示例中显示的表单,而不是kogus评论中显示的相关子查询表单.

在启动事务SNAPSHOTSERIALIZABLE隔离级别后,使用两个查询,如方法1中所示.

使用其中一个隔离级别非常重要,因为任何其他隔离级别都允许其他客户端创建的新行在当前事务中可见.有关SET TRANSACTION ISOLATION更多详细信息,请阅读MSDN文档.

推荐阅读
罗文彬2502852027
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有