使用 perl dbi 构建列表的哈希值,例如“所有 id 标签”

使用 perl dbi 构建列表的哈希值,例如“所有 id 标签”

我搜索了dbi文档并在 Google 上搜索,但找不到是否有 (dbi) 本机方法来构建列表的哈希值。我能想到的最接近的方法是,fetchall_hashref但它会覆盖结果,只给我最后一对。澄清一下,我的表是“id,tag”之类的对的列表。我希望按 id 对所有行进行分组并返回一个哈希值,其中键是 id,“值”是(引用)其所有标签的列表。因此,在以下情况下:

id1, tag1
id1, tag2
id2, tag3
id2, tag1

我想要得到:

{'id1' => ['tag1', 'tag2'],
 'id2' => ['tag3', 'tag1'] }

这可能吗?如果不可能,那么非本地执行此操作的最佳(最有效)方法是什么?显而易见的方法是只执行 fetchall_* + push() 组合,但有没有更好的方法?

答案1

这是我目前的方法:

my $ret = {};
foreach (@{ $sth->fetchall_arrayref(  ) }) { # returns ref to array
    push  @{ $ret->{ $_->[0] } }, $_->[1] ;
    }
return $ret;

如果它对某些人有用,我们会等待看看是否有更好的方法来做到这一点。


编辑:

我找到了另一种方法,即GROUP_CONCAT在 MySQL 中使用“标签”,并与唯一字符连接,然后split()在 perl 中使用。查询将类似于:

SELECT id, GROUP_CONCAT(tag, '|')
FROM mytable
GROUP BY tag

然后在 perl 中:

my $ret = {};
foreach (@{ $sth->fetchall_arrayref(  ) }) { # returns ref to array
    push  @{ $ret->{ $_->[0] } }, split("|", $_->[1]) ;
    }
return $ret;

未经测试的代码,因此适用标准警告。

我看到的唯一优点是这会从数据库返回较少的行,因此 foreach 的迭代次数会更少。也许有人可以分析一下这段代码,并让我们知道这些方法是否存在明显的速度差异。

相关内容