META_QUERY的XOR功能

时间:2013-04-03 作者:Kee Ross

我正在尝试解决事件显示的问题。

一个事件有它的开始和结束日期,用meta编写。例如,事件开始于(dmY)2013年4月3日,结束于2013年4月8日。使用WP_querymeta_query 如果我试图在2013年4月9日之前获取数据,我可以排除此事件。

同时,这项活动将在每天的间歇期内出现,这也很酷。但是,如果我想在2013年4月2日之前获取数据,我真的不能排除这个事件
我使用的时间间隔是这个月,例如从2013年4月1日到2013年4月30日。

这是代码
在我的特殊情况下,我需要XOR功能meta_relation. 最好的方法是创建自定义$wpdb 查询,但我对MySQL不是很在行。。。。

//Week events
$query_date = $_GET[\'date\'];
$month_start = date(\'Ym01\',strtotime(\'this month\'));
$month_end = date(\'Ymt\',strtotime(\'this month\'));
//IF query Day is empty
if ( empty($query_date) || ( strlen($query_date) != 8 ) || ( !is_numeric($query_date) ) ) {

  //Custom query
  $args = array(
    \'post_type\' => \'post\',
    \'orderby\' => \'event_start_date\',
    \'order\' => \'ASC\',
    \'meta_query\' => array(
    \'relation\' => \'OR\',
      array(
        \'key\' => \'event_start_date\',
        \'value\' => array( $month_start, $month_end),
        \'compare\' => \'BETWEEN\',
        \'type\' => \'DATE\'
      ),
      array(
        \'key\' => \'event_end_date\',
        \'value\' => array( $month_start, $month_end),
        \'compare\' => \'BETWEEN\',
        \'type\' => \'DATE\'
      )
    )
  );

} else {

  //Custom query
  $args = array(
    \'post_type\' => \'post\',
    \'orderby\' => \'event_start_date\',
    \'order\' => \'ASC\',
    \'meta_query\' => array(
    \'relation\' => \'OR\',
       array(
        \'key\' => \'event_start_date\',
        \'value\' => array( $query_date, $month_end),
        \'compare\' => \'BETWEEN\',
        \'type\' => \'DATE\'
       ),
       array(
        \'key\' => \'event_end_date\',
        \'value\' => array( $query_date, $month_end),
        \'compare\' => \'BETWEEN\',
        \'type\' => \'DATE\'
       )
     )
   );
  }

$wp_query = new WP_Query( $args );
//End of custom query

1 个回复
SO网友:Kee Ross

可以所以,为了找到一个正确的解决方案,我们花了整整一个晚上。。。最后我做到了。这是一种适合我的方法。

这个$wpbd 这个方法很酷,同时也很复杂。使用此方法时,不要忘记使用php-apcmemcache.

在做一些测试时意识到XOR 逻辑操作无法正常工作。所以,我用一个集合替换了XOR:XOR = ( ( A AND NOT B ) OR ( NOT A AND B ) ). 这个有效!

//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

结束