我想选择一个列从一个单一的表格(不同),我需要的数量的排,最好在我开始之前取行。我来了两种方法提供信息我需要的。

办法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本客户9.0)不允许我使用SQLRowCount在选择发言,但我需要知道行的数量在我的结果,以便拨出一系列前所分配的信息。使用一个动态分配的容器,不幸的是,并不是一个选项中的这个区域的我的程序。

我感到关切的是,以下情况可能会发生:

  • 选择为数发生
  • 另一个指令发生,添加或删除一排
  • 选择用于数据发生时和突然的阵列是错的大小。
    -在最坏的情况下,这将尝试写数据的阵列的限制和崩溃我的节目。

没办法2禁止这一问题?

此外,将两个办法能更快?如果是,哪个?

最后,是否有更好的办法,我应该考虑(或许是一种指示司机返回的数目排在一个选择的结果使用SQLRowCount?)

对于那些询问的,我用母C++与上述SQL司机(由微软公司提供。)

有帮助吗?

解决方案

只有两种方式可以100%确定 COUNT(*) 和实际的查询将得到一致的结果:

  • 合并的 COUNT(*) 与查询,因为在您的办法2.我建议的形式展示你的实例中,没有相关查询的形式表示的意见从kogus.
  • 使用两个查询,因为在办法1中,启动后交易 SNAPSHOTSERIALIZABLE 隔离水平。

使用这些隔离水平是重要的,因为任何其他的隔离水平允许新的行创建其他的客户成为在当前事务。读MSDN文件 SET TRANSACTION ISOLATION 更多的细节。

其他提示

如果你使用SQL服务器上,后您的询问你可以选择 @@RowCount 功能(或者如果你的结果设定的可能有超过2亿行使用 RowCount_Big() 功能)。这将返回的人数选择的行通过的先前的声明或行数受影响的insert/update/delete发言。

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

SELECT @@Rowcount

或者如果你想要的行计数包括在结果发送类似的方法#2,可以使用的 在条款.

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

使用过的条款会有很多更好的性能比用子查询获取的行数。使用@@RowCount将有最好的性能,因为将不会有任何查询的成本的选择@@RowCount声明

更新在应对评论意见:我给的例子会给#行分区的定义在这种情况下,通过"分区的忽略大小.foo"。值列在每一行为的行相同价值的忽略大小.foo。由于您的例子查询有条款,"其中忽略大小.foo='bar'",所有行的结果将具有同样价值的忽略大小.foo因此值在列将同所有行的和平等的(在这种情况下)这#中的行查询。

这里是一个更好/更简单的例子包括列在每个行总#行的结果集。简单地删除《任择分区通过条款。

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

办法2将始终返回计数相匹配的结果设定的。

我建议你的链子查询,以你的外部查询,虽然,为了保证的条件在您的计匹配的条件上的数据集。

SELECT 
  mt.my_row,
 (SELECT COUNT(mt2.my_row) FROM my_table mt2 WHERE mt2.foo = mt.foo) as cnt
FROM my_table mt
WHERE mt.foo = 'bar';

如果你言行的数量,以满足的条件可能会改变,在几毫秒,因为执行的查询和检索结果,可以/应当执行查询内部的事务:

BEGIN TRAN bogus

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'
ROLLBACK TRAN bogus

这将返回正确的价值观,永远。

此外,如果您使用的SQL服务器,可以使用@@ROWCOUNT获得的数量影响的行通过的最后声明,以及向输出 真的 查询一个临时表或表变量,这样你就可以返回的一切完全不必要的交易:

DECLARE @dummy INT

SELECT my_table.my_col
INTO #temp_table
FROM my_table
WHERE my_table.foo = 'bar'

SET @dummy=@@ROWCOUNT
SELECT @dummy, * FROM #temp_table

这里有一些想法:

  • 去,有办法#1和调整数组举行额外的结果或使用一种自动调整为必要的(你不说什么语言使用,所以我不能更具体的).
  • 你可以执行的陈述在方法1内的事务,以保证该计数是相同的两倍,如果你的数据库支持这一点。
  • 我不确定你是什么做的数据,但如果它能够处理结果没有存储所有的人首先这可能是最好的方法。

如果你真的很关切你的行计数会改变之间的选择计数和所选择的语句,为什么不选择你的行成临时表的第一次?这样,你知道,你会在同步。

为什么你不把你的结果成为一种矢量?这样你不必知道的尺寸之手。

你可能想考虑一个更好的图案处理数据的这种类型。

没有自prespecting SQL驱动程序会告诉你多少行查询将返回之前返回行,因为答案可能会改变的(除非你使用一种交易,这造成了问题。)

行的数量不会改变-谷歌酸和SQL。

IF (@@ROWCOUNT > 0)
BEGIN
SELECT my_table.my_col
  FROM my_table
 WHERE my_table.foo = 'bar'
END

只是添加这一点,因为这是顶级的结果在google这个问题。在源码我用这个来获得rowcount。

WITH temptable AS
  (SELECT one,two
   FROM
     (SELECT one, two
      FROM table3
      WHERE dimension=0
      UNION ALL SELECT one, two
      FROM table2
      WHERE dimension=0
      UNION ALL SELECT one, two
      FROM table1
      WHERE dimension=0)
   ORDER BY date DESC)
SELECT *
FROM temptable
LEFT JOIN
  (SELECT count(*)/7 AS cnt,
                        0 AS bonus
   FROM temptable) counter
WHERE 0 = counter.bonus
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top