You basically have the answer, just add $date2
to the inner sql where clause:
AND p.post_date > '$date2'
to get last week. To get a particular week, use
AND p.post_date < '$date1' AND p.post_date > '$date2'
where eg
$date1 = date('Y-m-d', strtotime('2014-07-04 +1 days'));
$date2 = date('Y-m-d', strtotime('2014-07-04 -8 days'));
To return weekly/total votes, you could put the test into the select clause:
$results = $wpdb->get_results ( "
SELECT u.display_name as name,
( SELECT
CONCAT_WS('.',
SUM(CASE WHEN p.post_date < '$date1' AND p.post_date > '$date2' THEN pm.meta_value ELSE 0 END),
SUM(pm.meta_value))
FROM wp_posts p, wp_postmeta pm
WHERE p.post_author = u.ID
AND p.post_status LIKE 'publish'
AND pm.meta_key = 'epicredvote'
AND p.ID = pm.post_id ) as votes
FROM wp_users u
ORDER BY votes+0 DESC LIMIT 20
" );
And then output results as desired:
foreach ($results as $result) {
$name = $result->name;
list( $weekly_vote, $total_vote ) = explode( '.', $result->votes ? $result->votes : '0.0' );
// do stuff with $name, $weekly_vote, $total_vote ...eg
echo 'Name: ', $name, ' Weekly Vote: ', $weekly_vote, ' Total Vote: ', $total_vote;
}