How to sort on different columns in the same view? I'm trying to build a Glossary View in Drupal 8. Let's say I have 3 content types: Person, Article, Event.  I want sort by title ASC for Article and Event, but sort by Last Name for Person.  So that listing would show something like.

Deep Study on Dolphins (article)
John Doe (person)
Jam in the Backyard (event)

And Not

Deep Study
Jam in the Backyard
John Doe

I think I can do this with hook_views_query_alter, but the only examples I've seen are for Drupal 7.

I've got something like this

function mymodule_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  if ($view-&gt;id() == 'glossary_everything') {
     $query-&gt;orderby[0]['field'] = "CASE WHEN node_field_data.last_name IS NULL THEN node_field_data.title ELSE node_field_data.last_name END";
  }
}


But I'm getting a "column not found" sql error.  I think it's treating the whole CASE statement as one big field.  Is that because of the ['field'] designation in my array?
In Drupal 8, if you want to alter an ORDER BY, in particular to use a formula, you have to add an expression and then order by it:

$query-&gt;addExpression('SUBSTRING(thread, 1, (LENGTH(thread) - 1))', 'order_field');
$query-&gt;orderBy('order_field', 'ASC');


There can be some confusion in Views, because their version of addExpression is Sql::addField. And in fact, Sql::addOrderBy let's you add a field and order by it in one call.

So, your code would look like:

$sql = &lt;&lt;&lt;SQL
CASE
     WHEN node_field_data.last_name IS NULL THEN node_field_data.title
          ELSE node_field_data.last_name
END
SQL;

$query-&gt;addField(NULL, $sql, 'last_name_else_title');
$query-&gt;orderby[] = array(
  'field' =&gt; 'last_name_else_title',
  'direction' =&gt; 'ASC',
);


Or just...

$query-&gt;addOrderBy(NULL, $sql, 'ASC', 'last_name_else_title');


Thanks agileadam for pointing out the failure point (see also).