문서를 검색 dbi
하고 검색했지만 목록 해시를 구축하는 (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
그런 다음 펄에서:
my $ret = {};
foreach (@{ $sth->fetchall_arrayref( ) }) { # returns ref to array
push @{ $ret->{ $_->[0] } }, split("|", $_->[1]) ;
}
return $ret;
테스트되지 않은 코드이므로 표준 경고가 적용됩니다.
내가 볼 수 있는 유일한 장점은 이것이 db에서 더 적은 행을 반환하므로 foreach의 반복 횟수가 줄어든다는 것입니다. 어쩌면 누군가가 이 코드를 프로파일링하여 접근 방식에 상당한 속도 차이가 있는지 알려줄 수 있을 것입니다.