web-dev-qa-db-ja.com

同じビューの異なる列で並べ替える方法は?

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']が指定されているためですか?

3
Greg

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に感謝( も参照 )。

3
ognockocaten

これは、$this->connection->escapeField($field)内の\Drupal\Core\Database\Query\Select::__toString()の呼び出しが原因です。

\Drupal\Core\Database\Connection::escapeFieldはスペースを一掃しているため(たとえば、CASE WHENがCASEWHENになる)、ステートメントが無効になります。

解決策を思いつく時間はありませんが、それが解決策となります。

2
agileadam

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');
0
hugronaphor