Drupal 8.で用語集ビューを作成しようとしています。Person、Article、Eventの3つのコンテンツタイプがあるとします。ArticleとEventのタイトルASCで並べ替えたいが、 Personの姓です。そのため、そのリストは次のようになります。
イルカに関する深い研究(記事)ジョンドー(人物)裏庭でのジャム(イベント)
そしてない
裏庭のジョン・ドウのディープ・スタディ・ジャム
私はこれをhook_views_query_alterで実行できると思いますが、私が見た例はDrupal 7。
私はこのようなものを持っています
function mymodule_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
if ($view->id() == 'glossary_everything') {
$query->orderby[0]['field'] = "CASE WHEN node_field_data.last_name IS NULL THEN node_field_data.title ELSE node_field_data.last_name END";
}
}
しかし、「列が見つかりません」というSQLエラーが発生します。 CASEステートメント全体を1つの大きなフィールドとして扱っていると思います。それは私の配列で['field']が指定されているためですか?
Drupal 8で、特に式を使用するためにORDER BYを変更する場合は、 式を追加 してから order by it :
$query->addExpression('SUBSTRING(thread, 1, (LENGTH(thread) - 1))', 'order_field');
$query->orderBy('order_field', 'ASC');
ビューのaddExpressionのバージョンは Sql :: addField であるため、ビューに混乱が生じる可能性があります。そして実際には、 Sql :: addOrderBy では、1回の呼び出しでフィールドを追加し、それを並べ替えましょう。
したがって、コードは次のようになります。
$sql = <<<SQL
CASE
WHEN node_field_data.last_name IS NULL THEN node_field_data.title
ELSE node_field_data.last_name
END
SQL;
$query->addField(NULL, $sql, 'last_name_else_title');
$query->orderby[] = array(
'field' => 'last_name_else_title',
'direction' => 'ASC',
);
あるいは単に...
$query->addOrderBy(NULL, $sql, 'ASC', 'last_name_else_title');
障害点を指摘してくれたagileadamに感謝( も参照 )。
これは、$this->connection->escapeField($field)
内の\Drupal\Core\Database\Query\Select::__toString()
の呼び出しが原因です。
\Drupal\Core\Database\Connection::escapeField
はスペースを一掃しているため(たとえば、CASE WHENがCASEWHENになる)、ステートメントが無効になります。
解決策を思いつく時間はありませんが、それが解決策となります。
this の例から、これは日付フィールドとNode公開日で並べ替える方法です。
$orderBySql = <<<ORDER_BY_SQL
CASE
WHEN node__field_date.field_date_value IS NULL THEN node_field_data.created
ELSE UNIX_TIMESTAMP(DATE_FORMAT(node__field_date.field_date_value, '%Y%m%d'))
END
ORDER_BY_SQL;
// Override existing Order rules.
$query->orderby = [];
$query->addOrderBy(NULL, $orderBySql, 'ASC', 'diff_date_fields');