Okay! So, having spent all the night in order to find a right solution... finally.. I did it. Here is the right method, that works in my situation. The `$wpbd` method is pretty cool and complicated at the same time. While using this method do not forget to cache queries properly with `php-apc` or `memcache`. While doing some testings realized, that `XOR` logic operation does not work properly. So, I replaced XOR by a set: `XOR = ( ( A AND NOT B ) OR ( NOT A AND B ) )`. This one works! //Week events $query_date = $_GET['date']; $month_start = date('Ym01',strtotime('this month')); $month_end = date('Ymt',strtotime('this month')); $pm1_meta_key = 'event_start_date'; $pm2_meta_key = 'event_end_date'; //IF query Day is empty if ( empty($query_date) ) { //Custom query $postids = $wpdb->get_col( $wpdb->prepare( " SELECT p.* FROM $wpdb->posts p JOIN $wpdb->postmeta pm1 ON (p.ID = pm1.post_id) JOIN $wpdb->postmeta pm2 ON (p.ID = pm2.post_id) WHERE p.post_type = 'post' AND p.post_status = 'publish' AND ( ( pm1.meta_key ='%1\$s' AND CAST( pm1.meta_value AS DATE) BETWEEN %3\$d AND %4\$d ) OR ( pm2.meta_key = '%2\$s' AND CAST( pm2.meta_value AS DATE ) BETWEEN %3\$d AND %4\$d ) ) ", $pm1_meta_key, $pm2_meta_key, $month_start, $month_end )); $args = array( 'post__in' => $postids, 'meta_key' => 'event_start_date', 'orderby' => 'meta_value_num', 'order' => 'ASC' ); } else { //Date $query_date = date('Ymd', strtotime($query_date)); $query_date_month = date('m', strtotime($query_date)); //If future month if ( $query_date_month > date('m') ) { $month_end = date('Ymt', mktime(0, 0, 0, $query_date_month, 1, date('y'))); } //Custom query $postids = $wpdb->get_col( $wpdb->prepare( " SELECT p.* FROM $wpdb->posts p JOIN $wpdb->postmeta pm1 ON (p.ID = pm1.post_id) JOIN $wpdb->postmeta pm2 ON (p.ID = pm2.post_id) WHERE p.post_type = 'post' AND p.post_status = 'publish' AND ( ( ( pm1.meta_key = '%1\$s' AND CAST( pm1.meta_value AS DATE) BETWEEN %3\$d AND %4\$d ) AND ( pm2.meta_key = '%2\$s' AND CAST( pm2.meta_value AS DATE ) NOT BETWEEN %3\$d AND %4\$d ) ) OR ( ( pm1.meta_key = '%1\$s' AND CAST( pm1.meta_value AS DATE) NOT BETWEEN %3\$d AND %4\$d ) AND ( pm2.meta_key = '%2\$s' AND CAST( pm2.meta_value AS DATE ) BETWEEN %3\$d AND %4\$d ) ) ) OR ( pm1.meta_key = '%1\$s' AND CAST( pm1.meta_value AS DATE) = %3\$d ) ", $pm1_meta_key, $pm2_meta_key, $query_date, $month_end ) ); $args = array( 'post__in' => $postids, 'meta_key' => 'event_start_date', 'orderby' => 'meta_value_num', 'order' => 'ASC' ); } $wp_query = new WP_Query( $args ); //End of custom query