How to combine multiple view result sets, limiting the combined result set I want to create a 'suggested content' display that, by default, displays 4 nodes that share terms on a term reference field belonging to the currently node. So, if the current node is tagged with "baking" and "family", it should display nodes that have those terms in common. I have this working — all is good here.

Also, on the reference node I've added an entity reference field that allows editors to curate their own suggested content. My intention is to put this curated content at the beginning of the suggested results, so that if an editor specifies 2 nodes, the other view will populate the other 2 nodes.

Basically, what I think I need to do (correct me if I'm wrong), is to combine the results from two views (one displaying the curated nodes, the other displaying the term-related nodes), and limit them to the top 4 entries, ensuring that the curated nodes are displayed first.

If this was confusing, this image should make it clearer;


How can I combine the results from two views and limit the combined result set? Also, note that each view only uses a single field for each row (a rendered node).
Here's what I ended up doing (not using views). I'm using Panels on this site, and my default view for this content-type is controlled via Panelizer. Since I couldn't find a way to do this with Views, I created a custom panels pane (code below).

Basically, this pane accepts one setting: the number of related events to display. The render callback counts the editor-defined related nodes, and grabs more (if needed) based on shared terms.

&lt;?php

$plugin = array(
'single' =&gt; TRUE,
'title' =&gt; t('Suggested Events'),
'description' =&gt; t('Combines curated suggested events with those related by category.'),
'category' =&gt; t('Custom Panes'),
'edit form' =&gt; 'MYMODULE_suggested_events_edit_form',
'render callback' =&gt; 'MYMODULE_suggested_events_render',
'admin info' =&gt; 'MYMODULE_suggested_events_info',
'defaults' =&gt; array(
  'events_to_show' =&gt; 4
),
'all contexts' =&gt; TRUE,
);


/**
 * Edit Form.
 */
function MYMODULE_suggested_events_edit_form($form, &amp;$form_state) {
$conf = $form_state['conf'];

$form['events_to_show'] = array(
  '#title' =&gt; t('Number of events to show'),
  '#description' =&gt; t('Used to control the number of suggested events shown. Defaults to 4.'),
  '#type' =&gt; 'select',
  '#options' =&gt; drupal_map_assoc(range(3, 6)),
  '#default_value' =&gt; $conf['events_to_show'],
  '#required' =&gt; TRUE,
);

return $form;
}


/**
 * Submit callback for settings form.
 */
function MYMODULE_suggested_events_edit_form_submit($form, &amp;$form_state) {

foreach (array_keys($form_state['plugin']['defaults']) as $key) {
  if (isset($form_state['values'][$key])) {
    $form_state['conf'][$key] = $form_state['values'][$key];
  }
}
}


/**
 * Run-time rendering of the content
 */
function MYMODULE_suggested_events_render($subtype, $conf, $args, $contexts) {

  if (isset($contexts['panelizer'])) {
    $nid = $contexts['panelizer']-&gt;data-&gt;nid;
  } else {
    return false;
  }

  // Grab the Category Term IDs from referenced node.
  $node = node_load($nid);
  $categoryField = field_get_items('node', $node, 'field_category');
  $categoryTIDs = array_column($categoryField, 'tid');

  // suggestedEvents are the events which are selected by the editor.
  $suggestedEventsField = field_get_items('node', $node, 'field_event_suggested');

  if (empty($suggestedEventsField)) {
    $suggestedEvents = array();
  } else {
    $suggestedEventsNIDs = array_column($suggestedEventsField, 'target_id');
    $suggestedEvents = entity_load('node', $suggestedEventsNIDs ); // @returns array of entities
  }


  // determine how many events we need to find 
  // based upon the total to display and how many are site-editor-defined
  $relatedEvents = array();
  $relatedEventsCount = 0;
  if (count($suggestedEvents) &lt; $conf['events_to_show']) {
    $relatedEventsCount = $conf['events_to_show'] - count($suggestedEvents);
  }

  if ($relatedEventsCount &gt; 0) {
    // Query for other events that share the referenced categories.
    $query = new EntityFieldQuery();
    $query-&gt;entityCondition('entity_type', 'node')
      -&gt;entityCondition('bundle', 'event')
      -&gt;propertyCondition('status', NODE_PUBLISHED)
      -&gt;propertyCondition('nid', $nid, '&lt;&gt;')
      -&gt;fieldCondition('field_category', 'tid', $categoryTIDs, 'IN')
      -&gt;fieldCondition('field_datetime', 'value', date('Y-m-d').'00:00:00', '&gt;=', 0)
      -&gt;range(0, $relatedEventsCount)
      // Run the query as user 1.
      -&gt;addMetaData('account', user_load(1));

    $result = $query-&gt;execute();
    if (isset($result['node'])) {
      $relatedEventsNIDs = array_keys($result['node']);
      $relatedEvents = entity_load('node', $relatedEventsNIDs);
    } 
  }

  $events = array_merge($suggestedEvents, $relatedEvents);

  $block = new stdClass();
  $block-&gt;title = 'You may also enjoy...';
  $block-&gt;content = '';
  if (!empty($events)) {
    $block-&gt;content .= '&lt;div class="block__content"&gt;';
    $eventsRenderArray = entity_view('node', $events, 'showcase_card');
    $block-&gt;content .= render( $eventsRenderArray );
    $block-&gt;content .= '&lt;/div&gt;';

    return $block;
  } else {
    return false;
  }


}


/**
 * Admin info.
 */
function MYMODULE_suggested_events_info($subtype, $conf, $contexts) {
if (!empty($conf)) {
  $block = new stdClass;
  $block-&gt;title = $conf['override_title'] ? $conf['override_title_text'] : '';
  $block-&gt;content = t('Show @events_to_show suggested events.', array(
    '@events_to_show' =&gt; $conf['events_to_show']
  ));

  return $block;
}
}