进行 SQL SELECT 查询时,如何获取项目数?

发布于 2024-11-10 00:07:17 字数 605 浏览 6 评论 0原文

我正在使用 Dancer 框架在 Perl 中编写一个 Web 应用程序。数据库在sqlite中,我使用DBI进行数据库交互。

我对 select 语句很满意,但我想知道是否有一种方法可以计算所选行的数量。

例如,我

get '/' => sub {
    my $content = database->prepare(sprintf("SELECT * FROM content LIMIT %d",
            $CONTNUM));
    $content->execute;
    print(Dumper($content->fetchall_arrayref));
};

如何在不发出另一个查询的情况下计算结果中的所有项目?

我想要通过这种方式实现的是每页显示 30 个项目并知道会有多少页。当然,我可以运行 SELECT COUNT (*) foo bar,但对我来说它看起来是错误且多余的。我正在寻找一种或多或少通用的、DRY 并且不太依赖数据库的方法来做到这一点。

任何 SQL 或 Perl hack 或提示我应该阅读什么内容将不胜感激。

// 我知道使用字符串连接进行查询是不好的

I'm writing a web app in Perl using Dancer framework. The database is in sqlite and I use DBI for database interaction.

I'm fine with select statements, but I wonder is there a way to count selected rows.

E.g. I have

get '/' => sub {
    my $content = database->prepare(sprintf("SELECT * FROM content LIMIT %d",
            $CONTNUM));
    $content->execute;
    print(Dumper($content->fetchall_arrayref));
};

How do I count all items in the result without issuing another query?

What I want to achieve this way is showing 30 items per page and knowing how many pages there would be. Of course I can run SELECT COUNT (*) foo bar, but it looks wrong and redundant to me. I'm looking for a more or less general, DRY and not too heavy on database way to do so.

Any SQL or Perl hack or a hint what should I read about would be appreciated.

// I know using string concatenation for querys is bad

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

内心荒芜 2024-11-17 00:07:17

您必须以困难的方式做到这一点:一个查询获取计数,另一个查询获取所需的行集切片:

my $count = $database->prepare('SELECT COUNT(*) FROM content');
$count->execute();
my $n = $count->fetchall_arrayref()->[0][0];

my $content = $database->prepare('SELECT * FROM content LIMIT ?');
$content->execute($CONTNUM);
#...

You have to do it the hard way: one query to get the count and another to get your desired slice of the row set:

my $count = $database->prepare('SELECT COUNT(*) FROM content');
$count->execute();
my $n = $count->fetchall_arrayref()->[0][0];

my $content = $database->prepare('SELECT * FROM content LIMIT ?');
$content->execute($CONTNUM);
#...
落在眉间の轻吻 2024-11-17 00:07:17

对 perl 不太熟悉,但我假设您可以存储 $content->fetchall_arrayref 的结果并在打印之前从该数组中检索计数。

[编辑]

类似的东西

my $ref = $content->fetchall_arrayref;
my $count = scalar(@$ref);

Not too familiar with perl, but I assume you can just store the result of $content->fetchall_arrayref and retrieve the count from that array befor you print it.

[edit]

Something like

my $ref = $content->fetchall_arrayref;
my $count = scalar(@$ref);
断爱 2024-11-17 00:07:17

我自己不要使用 sqlite,但以下方法可能会起作用:

select * from table join (select count(*) from table);

无论以上是否有效,如果您要翻阅结果,我首先要寻找的是可滚动游标 - 我怀疑 sqlite 有这些。但是,在 DBI 中,您可以使用 fetchall_arrayref 和 max_rows 一次获取一个“页面”。只需在 fetchall_arrayref 下的 DBI 文档中查找示例 - 它是这样的:

my $rowcache = [];
while( my $row = ( shift(@$rowcache) || shift(@{$rowcache=$sth->fetchall_arrayref(undef,100)||[]}) )
         ) {
           # do something here
         }

更新:添加了使用 selectall_hashref 得到的内容,假设该表被称为内容,其中有一个名为“a”的整数列:

$ perl -le 'use DBI; my $h = DBI->connect("dbi:SQLite:dbname=fred.db"); my $r = $h->selectall_hashref(q/select * from content join (select count(*) as count from content)/, "a");use Data::Dumper;print Dumper($r);'
$VAR1 = {
          '1' => {
                   'count' => '3',
                   'a' => '1'
                 },
          '3' => {
                   'count' => '3',
                   'a' => '3'
                 },
          '2' => {
                   'count' => '3',
                   'a' => '2'
                 }
        };

Don't use sqlite myself but the following might work:

select * from table join (select count(*) from table);

Whether the above works or not the first thing I'd look for is scrollable cursors if you are going to page through results - I doubt sqlite has those. However, in DBI you can use fetchall_arrayref with a max_rows to fetch a "page" at a time. Just look up the example in the DBI docs under fetchall_arrayref - it is something like this:

my $rowcache = [];
while( my $row = ( shift(@$rowcache) || shift(@{$rowcache=$sth->fetchall_arrayref(undef,100)||[]}) )
         ) {
           # do something here
         }

UPDATE: Added what you'd get with selectall_hashref assuming the table is called content with one integer column called "a":

$ perl -le 'use DBI; my $h = DBI->connect("dbi:SQLite:dbname=fred.db"); my $r = $h->selectall_hashref(q/select * from content join (select count(*) as count from content)/, "a");use Data::Dumper;print Dumper($r);'
$VAR1 = {
          '1' => {
                   'count' => '3',
                   'a' => '1'
                 },
          '3' => {
                   'count' => '3',
                   'a' => '3'
                 },
          '2' => {
                   'count' => '3',
                   'a' => '2'
                 }
        };
晨曦慕雪 2024-11-17 00:07:17

如果您想知道会有多少结果,并在一个查询中获取结果本身,则将计数作为新值获取:

SELECT COUNT(*) AS num_rows, * from Table WHERE ...

现在行计数将是结果集每行的第一列,因此,只需在呈现数据之前将其弹出即可。

If you want to know how many results there will be, as well as getting the results themselves, all in one query, then get the count as a new value:

SELECT COUNT(*) AS num_rows, * from Table WHERE ...

Now the row count will be the first column of every row of your resultset, so simply pop that off before presenting the data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文