【问题标题】:How to get the number of rows of the selected result from sqlite3?如何从 sqlite3 中获取所选结果的行数?
【发布时间】:2021-11-16 20:52:50
【问题描述】:

我想获取所选行数以及所选数据。目前我要使用两条sql语句:

一个是

select * from XXX where XXX;

另一个是

select count(*) from XXX where XXX; 

单条sql字符串可以实现吗?

我查看了sqlite3的源码,发现sqlite3_changes()的功能。但该功能仅在数据库更改时(insert, delete or update 之后)才有用。

谁能帮我解决这个问题?非常感谢!

【问题讨论】:

  • 虽然答案是肯定的,但下面的大多数答案都会增加您应该避免的复杂性。运行两个查询没有任何问题。如果您在查询后处理数据,您还可以使用生成的集合对象的 count()size() 方法,具体取决于您使用的语言。
  • 我进行查询,然后将每一行转换为 C++ 对象并将行添加到 C++ std::vector。显然,我想尽可能高效地做到这一点。如果您首先为正确数量的项目保留空间,则将项目添加到 std::vector 会明显更快。因此,首先进行查询以获取计数是没有意义的,因为它比我从知道计数中节省下来的效率更高,并且在最后查询我的 std::vector 也是毫无意义的,因为这为时已晚。

标签: sqlite count


【解决方案1】:

试试这个方法

select (select count() from XXX) as count, * 
from XXX;

【讨论】:

  • 第一行本身对我有用“select (select count() from XXX) as count;” ...谢谢。
  • 如果您希望获得行数,则第一行过于复杂。只需执行“SELECT COUNT(*) AS count FROM xxx;”即可。
【解决方案2】:

SQL 不能混合使用单行(计数)和多行结果(从表中选择数据)。这是返回大量数据的常见问题。以下是一些处理此问题的提示:

  • 读取前 N 行并告诉用户“有超过 N 行可用”。不是很精确,但通常足够好。如果您保持光标打开,您可以在用户点击视图底部时获取更多数据(Google 阅读器会这样做)

  • 与其直接选择数据,不如先将其复制到临时表中。 INSERT 语句将返回复制的行数。稍后,您可以使用临时表中的数据来显示数据。你可以给这个临时表添加一个“行号”,让分页更简单。

  • 在后台线程中获取数据。这允许用户在数据网格或表格填充更多数据时使用您的应用程序。

【讨论】:

    【解决方案3】:
    select (select COUNT(0) 
                from xxx t1 
                where t1.b <= t2.b 
                ) as 'Row Number', b from xxx t2 ORDER BY b; 
    

    试试this

    【讨论】:

    • 这实际上为您的输出行添加了一个索引,但不计算行数(直到您到达最后一行),这并不比“SELECT * FROM xxx;”好并计算返回 SQLITE3_ROW 的 sqlite3_row() 的数量,它还会对可能出乎意料的输出进行排序。
    【解决方案4】:

    您可以将它们组合成一个语句:

    select count(*), * from XXX where XXX
    

    select count(*) as MYCOUNT, * from XXX where XXX
    

    【讨论】:

    • 这只返回行数和最后一行。
    【解决方案5】:

    要获取唯一标题的数量,您需要将 DISTINCT 子句传递给 COUNT 函数,如下语句:

    SELECT
     COUNT(DISTINCT column_name)
    FROM
     'table_name';
    

    来源:http://www.sqlitetutorial.net/sqlite-count-function/

    【讨论】:

      【解决方案6】:

      一旦你已经有了select * from XXX的结果,你就可以在你的程序中找到数组长度对吗?

      【讨论】:

      • 我可以。但直到我遍历所有结果行。我想尽快得到计数
      • 在这种情况下,我想运行两个 SQL 查询确实是最简单的解决方案。
      【解决方案7】:

      对于那些仍在寻找另一种方法的人,我发现获得总行数的更优雅的方法是使用 CTE。 这确保计数只计算一次:

      WITH cnt(total) as (SELECT COUNT(*) from xxx) select * from xxx,cnt
      

      唯一的缺点是如果需要 WHERE 子句,它应该在主查询和 CTE 查询中应用。

      在第一条评论中,Alttag 说运行 2 个查询没有问题。我不同意这一点,除非两者都是独特交易的一部分。如果没有,源表可以通过来自另一个线程/进程的任何 INSERT 或 DELETE 在 2 个查询之间进行更改。在这种情况下,计数值可能是错误的。

      【讨论】:

        【解决方案8】:
        int rows_count = 0;
        
        while (sqlite3_step(stmt) == SQLITE_ROW)
        {
            rows_count++;
        }
        
        // The rows_count is available for use
        
        sqlite3_reset(stmt);  // reset the stmt for use it again
        
        while (sqlite3_step(stmt) == SQLITE_ROW)
        {
            
            // your code in the query result
        
        }
        

        【讨论】:

          【解决方案9】:

          如果您使用sqlite3_get_table 而不是prepare/step/finalize,您将在一个数组(“结果表”)中一次获得所有结果,包括列数和名称以及行数。然后你应该使用sqlite3_free_table释放结果

          【讨论】:

          • 那么,如果您有 90 亿行,您希望填满整个内存和硬盘驱动器只是为了知道您有多少行?这比使用 count += sqlite3_step() == SQLITE3_ROW; 进行 for 循环更糟糕;
          • 链接页面显示“这是为向后兼容而保留的旧接口。不建议使用此接口。”
          猜你喜欢
          • 2014-11-03
          • 2021-12-28
          • 1970-01-01
          • 2015-08-09
          • 1970-01-01
          • 1970-01-01
          • 2017-11-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多