#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper qw(Dumper);

sub join_by_value {
  my ($hash) = @_;

  my %result = ();
  while (my ($key, $value) = each %$hash) {
    push @{$result{$value}}, $key;
  }

  return %result;
}

my %h = (
  'qwe' => 'q1',
  'asd' => 'q2',
  'zxc' => 'q3',
  'vbn' => 'q2',
  'rty' => 'q1',
  'fgh' => 'q3'
);

my %joined = join_by_value(\%h);
print Dumper(\%joined);
