Display posts by combining multiple meta key

As Tim Malone said, WP_Query isn’t going to return multiple copies of the same post in its result set. I think you have a design problem and I would suggest you use parent/child posts rather than post meta to accomplish what you want.

The following is one approach to doing this. First, register both post types:

// The parent event type
// There will be one of these for Radio Show and TV Show
register_post_type( 'event', $args );

// A non-public event type for each "occurrence" of an event
// There will be two of these for each Radio Show and TV Show
register_post_type( 'event_occurrence', array(
    // add all of your usual $args and then set public to false
    'public' => false,
) );

Then, when saving your event post, don’t save the start/end times as post meta on that post object. Instead use those dates to create event_occurrence posts for each occurrence, with the start and end times saved there.

$occurrence_id = wp_insert_post( array(
    // add all of your occurrence details and then set the parent
    // to the `event` post that's being saved
    'post_parent' => <event_post_id>,

    // Set the post date to the start time for efficient ordering
    'post_date' => $start_time,
) );

// Save the end time as post meta
// Save it as a Unix timestamp so that we can compare it in the query
update_post_meta( $occurrence_id, 'end_time', strtotime( $end_time ) );

Now you should have the following posts in the database:

Radio Show
    Radio Show Instance 1
    Radio Show Instance 2
TV Show
    TV Show Instance 1
    TV Show Instance 2

You can then query the occurrences like this:

$args = array(

    // Only fetch occurrences
    'post_type' => 'event_occurrence',

    // Retrieve only future occurrences
    'date_query' => array(
        array(
            'after' => 'now',
        )
    ),

    // use a reasonably high posts_per_page instead of -1
    // otherwise you could accidentally cripple a site
    // with an expensive query
    'posts_per_page' => 500,

    'post_status' => 'publish',

    'meta_query' => array(
        array(
            'key' => 'end_time',
            'value' => time(),
            'compare' => '>='
        ),
    ),

    // They'll be ordered by start date.
    // ASC starts with earliest first
    'order' => 'ASC',
);

Our loop will now contain four posts:

Radio Show Instance 1
Radio Show Instance 2
TV Show Instance 1
TV Show Instance 2

So while you’re looping through the occurrences, you can access the parent post of each occurrence to get the overall event data. You can do this with a simple function:

$parent_event_id = wp_get_post_parent_id( get_the_ID() );

However, this will result in a lot of extra queries to the database which will effect performance. Instead, I’d recommend you run a separate query for the primary event posts, and then pull them from those results, so you’re only making one additional query to the database:

$args = array(
    'post_type' => 'event',
    'date_query' => array(
        array(
            'after' => 'now',
        )
    ),
    'posts_per_page' => 500,
    'post_status' => 'publish',
    'meta_query' => array(
        array(
            'key' => 'end_time',
            'value' => time(),
            'compare' => '>='
        ),
    ),
    'order' => 'ASC',
);
$events = new WP_Query( $args );

So your $occurrences loop would look like this:

$occurrences = new WP_Query( $occurrences_args );
while( $occurrences->have_posts() ) {
    $occurrences->the_post();

    // Get the parent event data
    $parent_event_id = wp_get_post_parent_id( get_the_ID() );
    $parent_event = null;
    foreach ( $events->posts as $post ) {
        if ( $post->ID == $parent_event_id ) {
            $parent_event = $post;
            break;
        }
    }

    // Now you can use the loop to access the
    // occurrence data and use $parent_event to
    // access the overall event data
}