1

Я искал документы dbi и гуглил, но не мог найти, был ли (dbi) нативный способ создания хеша списков. Самое близкое, о чем я могу подумать, это fetchall_hashref но это перезаписывает результаты, давая мне только то, что было последней парой. Чтобы уточнить, моя таблица представляет собой список пар чего-то вроде «id, tag». Я хочу сгруппировать все строки по идентификатору и вернуть хеш, где ключ - это идентификатор, а "значение" - это (ссылка на) список всех его тегов. Так в случае:

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

Я хочу получить:

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

Это возможно? Если нет, то какой самый лучший (самый эффективный) способ сделать это не родным образом? Очевидным подходом было бы просто сделать комбо fetchall_ * + push (), но есть ли лучший способ?

1 ответ1

0

Вот мой текущий подход:

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. Может быть, кто-то может профилировать этот код и сообщить нам, если есть какие-либо существенные различия в скорости в подходах.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .