Question: I have a custom post type `event` in WordPress, and I need to query upcoming `event` `posts` comparing `$current_date`.

Query conditions are :

* `start_date` is a valid `date` always
* `end_date` can be a valid `date` or `null` or `empty` string.
* IF `end_date` is a valid `date` in db record then compare `end_date >= $current_date`
* ELSE IF `end_date` is `null` or `empty` then compare `start_date >=$current_date`.

Now If `end_date` was not optional , I could use below code to get desired results.

```
$args= array();
$args['post_type'] = "event";
$args['meta_query'] = array(
      array(
           'key'        => 'end_date',
           'compare'    => '>=',
           'value'      => date("Ymd",$current_date),
       )
);
$post_query = new WP_Query();
$posts_list = $post_query->query($args);

```

My problem is, how do I handle optional `end_date` in above code.

Thanks in advance.

Edit:
Reformatted code and text above to make it more clear

Answer: 
I think I know what you are going through ... I recently had to deal with a situation where I was (among other things) comparing a meta value that may or may not exist.

The solution I found involved a very crazy SQl statment, with a WHERE IF clause.

In your case, it could look something like this (explanation below):

```
global $wpdb;

// prepare SQL statement
$sql = $wpdb->prepare("
  SELECT * 
  FROM $wpdb->posts
  INNER JOIN $wpdb->postmeta
    ON $wpdb->posts.ID = $wpdb->postmeta.post_id
  WHERE post_type = 'event'
    AND post_status = 'publish'
    AND IF(
      (
        SELECT COUNT( post_id) 
        FROM $wpdb->postmeta 
        WHERE meta_key = 'end_date' 
        AND post_id = ID 
      ) > 0,
      meta_key = 'end_date',
      meta_key = 'start_date'
    )
    AND meta_value >= %s
  LIMIT %d
", date( 'Ymd'), 10 );

// get results
$results = $wpdb->get_results( $sql );

// iterate through results
foreach( $results as $result ) {
  setup_postdata( $result );

  // your loop
}

```

(Note this was tested on a similar setup, but not with your exact post meta fields. Might need a bit of tweaking).

First, we get the global `wpdb` variable, to access the raw wordpress db.

Then we prepare an SQL query which gets posts and joins them with post meta values (for comparison)

BUT. Here is the trick. The WHERE Statement has both `meta_key`, `meta_value`.

We know `meta_value` is always the same, which is the current date.

So for `meta_key` we run an IF statement that checks how many post meta rows the current post ID has where its meta key is equal to 'end\_date'.

If it has more than 0 rows, then set `meta_key` to 'end\_date' (second argument in the IF function), otherwise set it to 'start\_date' (third argument).

We also check post type and make sure they are published and limit the return to 10 (or whatever you'd like).

Finally, we fetch the results to use them as we please.

I know its a bit of a hack, but it works. Its also a bit slow, so might be worth caching the results

Hope that's what you are looking for! And if you find a better solution, please let me know :)
```
//  $startday, $endday - format YYYY-MM-DD and field format: YYYY-MM-DD      
        $args= array();    
        $args['post_type'] = "event";
        $args['meta_query'] = array(
              relation' => 'OR',   
              array(
                            'key'        => 'end_date',
                            'value' => array( $startday, $endday ),
                            'type' => 'DATE',
                            'compare' => 'BETWEEN'
               ),       
              array(
                            'key'        => 'start_date',
                            'value' => array( $startday, $endday ),
                            'type' => 'DATE',
                            'compare' => 'BETWEEN'
               )          
        );
        $post_query = new WP_Query();
        $posts_list = $post_query->query($args);

```

Perhaps again I did not understand you