сгруппировать два столбца из БД в perl - PullRequest
0 голосов
/ 08 ноября 2011

Я пишу сценарий, который требует группировки, и я не могу сделать их в SQL. Я получаю свои результаты как ArrayReference. Мой запрос к БД возвращает что-то вроде этого.

1234 TIN
32364 TIN
34367 BOX
87484 TIN
45674 BOX
45476 TIN
4575  BOX

Я хочу, чтобы они были сгруппированы как:

These are the list of BOX: 4575,45674,34367.

These are the list of TIN: 1234,32364,87484,45476.

Есть предложения, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 08 ноября 2011

Так как именно выглядит ссылка на ваш массив?

Это массив массивов, подобный этому:

@myArray = [
              [
                  1234,
                  TIN,
              ]
              [
                  32364,
                  TIN,
              ]
                  34367,
                  BOX,
              ]
          ]

Или массив хэшей:

       =  [
              {
                  NUMBER => 1234,
                  TYPE   => TIN,
              }
          ]

Или каждая строка представляет собой единичное возвращение некоторой формы fetch?Существует пять различных способов возврата данных из базы данных с использованием интерфейса DBI:

  • fetchrow_arrayref
  • fetchrow_array
  • fetchrow_hashref
  • fetchall_arrayref
  • fetchall_hashref

Предполагается, что вы использовали fetchall_arrayref, вот пример программы, которая будет делать то, что вы хотите:

use strict;
use warnings;
use feature qw(say switch);
use Data::Dumper;

my $fetchedSqlData = [
                  [ qw(1234 tin) ],
                  [ qw(3434 box) ],
                  [ qw(4341 tin) ],
                  [ qw(2343 box) ],
              ];


my @tinList;
my @boxList;

foreach my $row (@{$fetchedSqlData}) {
    if ($row->[1] eq "tin") {
        push @tinList => $row->[0];
    }
    else {
        push @boxList => $row->[0];
    }

}

say "These are the list of BOX: " . join ", " => @boxList;
say "These are the list of TIN: " . join ", " => @tinList;

Лучшим способом было бы иметь один хешоснованный на значении в столбце 2, и каждый хеш будет ссылкой на массив:

my %typeHash;
foreach my $row (@{$fetchedSqlData}) {
    $typeHash{$row->[1]} = [] if not exist $typeHash{$row->[1]};
    push @{$typeHash{$row->[1]}} => $row->[0];
}

Это немного более запутанно, но будет более гибким, если вы добавите тип "CRATE" в свой список.

Вывод данных из этого будет:

foreach my $type (sort keys %typeHash) {
    say "These are the list of $type: " . join ", " => $typeHash{$type}->[0];
}

Кстати, я не проверял этот хэш массивов, так что ожидайте ошибок кодирования.И да, я знаю, что мне не нужно делать $typeHash{$row->[1]) = [] if not exists $typeHash{$row->[1]}, но мне нравится это делать, потому что он гарантирует, что я храню правильный тип данных в элементе хеш-функции.

Чтобы тщательно протестировать этоЯ должен был бы создать базу данных и выполнить DBI fetchall_arrayref, чтобы точно проверить, как возвращаются данные.Я основываю это на своей неустойчивой памяти на том, как DBI работал, когда я последний раз использовал его, и на документации.

Возможно, есть способ сделать это с map, но я, как правило, не нашел map быть более эффективным, чем простая петля.

0 голосов
/ 08 ноября 2011

Если вы настаиваете на том, чтобы не использовать базу данных для этого, то следующий код выполнит базовую группировку.

# Assume data is in @rows
my %group;
push @{ $group{$_->[1]} }, $_->[0] for @rows;

while (my ($key, $items) = each %group) {
    print "These are the list of $key: ". join(',', @$items) .".\n";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...