This is really not a Perl question but a SQL question. In any case, you do not need the COUNT
column as SQLite provides a builtin count
function to do the counting for you:
SELECT str, countr(str) FROM mytable GROUP BY str
should give you each unique str
and the number of times it appears in the table.
Of course, if you defined your table with str
as the primary key, you cannot insert multiple str
s by definition, so your table structure needs to be refined.
UPDATE:
If I were to do this (and I am not sure I would), I would set up a table with an autogenerated id
column and a column for the string. SQLite's INTEGER PRIMARY KEY, a 64-bit integer would be sufficient to assign a unique id to each string inserted.
Then, I would use the query above to get the frequencies by string.
If you are inserting via Perl's DBI, make sure to turn AutoCommit
off during insertion and remember to commit at the end (or periodically).
Creating an index seems almost mandatory but it should be done after all the strings are in the database and before any queries are run.
#!/usr/bin/perl
use strict; use warnings;
use DBI;
my $dbh = DBI->connect('dbi:SQLite:counter.db', undef, undef,
{ RaiseError => 1, AutoCommit => 0 },
);
my $sth = $dbh->prepare(q{
INSERT INTO strings (string) VALUES(?)
});
my @strings = qw( 0123456789 9876543210 );
for ( 1 .. 10 ) {
my $val = $strings[0.5 > rand];
$sth->execute($val);
}
$dbh->commit;
my $result = $dbh->selectall_hashref(
q{SELECT string, count(string) FROM strings GROUP BY string},
'string',
);
$dbh->disconnect;
use Data::Dumper;
print Dumper $result;
The SQL:
DROP TABLE strings;
CREATE TABLE strings (
id INTEGER PRIMARY KEY,
string char(10)
);
Output:
$VAR1 = {
'9876543210' => {
'count(string)' => '9',
'string' => '9876543210'
},
'0123456789' => {
'count(string)' => '1',
'string' => '0123456789'
}
};