my %cars = ( 1002 => { make_id => 10, model_id => 27, year => 2001, price => 24000, }, ); my %makes = { 1 = "Chevrolet", 10 = "Acura", }; my %models = { 12 = "Camaro", 27 = "RSX", }; #### my %makes_idx = ( 1 => [1001, ... ], # cars that are Chevys 10 => [1002, ...], # cars that are Acuras ... ); #### my %years_idx = ( 2001 => [ 1001, 1002, ... ], # cars that are 2001 models ... ); #### # For example, finding all 2001 or newer Chevys my %temp_hash = reverse %makes; # gives the id for each make my $make_id = $temp_hash{'Chevrolet'); # get the id for Chevy my %make_set = map { $_=>1 } @{$makes_idx{$make_id}}; # set of cars that are Chevys # search above for 2001 or newer models my @temp_years = grep { $_ >= 2001 } keys %years_idx; my @result_ids = grep { exists $make_set{$_} } @years_idx{@temp_years};