web-dev-qa-db-ja.com

ビューのSelectQueryオブジェクト内でMySQL FIELD()関数を使用するにはどうすればよいですか?

MySQLのFIELD()関数を使用して、特定のキーの順序で特定のフィールドを並べ替えるようにクエリを変更したいと思います。

この「選択」フィールドのキーは、アクティブ、アンダーコントラクト、販売です

すべての結果が並べ替えられるようにビューを並べ替えたいfirst by _node.created DESC_(これはもちろん単純です)、次にすべてのsoldノードを結果の下部。

私は最初にhook_views_post_execute()でこれをやってみました:

_function mymodule_views_post_execute(&$view) {
  if ($view->name == 'my_view') {
    usort($view->result, function($a, $b) {
      return ($a->field_field_status[0]['raw']['value'] == 'sold') ? 1 : -1;
    });
  }
}
_

しかし、私のビューではページごとに25件の結果しか表示されないため、これはsoldノードを各ページの下部にのみプッシュすることがすぐにわかりました。

次に、hook_views_query_alter()を使用して、発見した素晴らしいMySQL FIELD()関数を追加しようとしました。これは、MySQLで完全に目標を達成するために機能しますが、追加できません(少なくとも私が発見しているように)ビューがクエリを実行するために使用するSelectQueryオブジェクトに:

_function mymodule_views_query_alter(&$view, &$query) {
  if ($view->name == 'my_view') {
    $query->orderby[0] = array(
      'field' => " FIELD(field_data_field_status.field_status_value, 'sold') ",
      'direction' => 'DESC',
  );
  }
}
_

このクエリにFIELD() orderby関数を追加するにはどうすればよいですか?特定のフィルター値を結果キューの一番下にプッシュする別の方法はありますか?

2

私はこれを手に入れました! orderByhook_views_query_alter()で動作させる方法が見つからなかったため、未加工のhook_query_alter()でこれを実行しようとしました。私の特定の状況では、ビューが既に結合しているテーブルに対してフィルターをかけたときに結果が得られなかったため(理由を説明できません)、独自の結合を追加しました。出来上がり、動作します。

function mymodule_query_alter($query) {
  if ($query->hasTag('my_view_id')) {
    // Remove the current sort order. 
    $order =& $query->getOrderBy();
    $order = array();

    // Join with the table that we need, giving it a custom alias.
    $query->join('field_data_field_listing_status', 'custom_status', 'custom_status.entity_id = node.nid');

    // Add our cool FIELD() function to Push all 'sold' nodes to the very back of the list.
    $query->orderBy("FIELD(custom_status.field_listing_status_value, 'sold')", 'ASC');

    // Add any other ordering that we need...
    $query->orderBy('node_created', 'DESC');
  }
}
3

以前の答えに基づいて構築(ありがとう)。私はviews API内でそれを行う方法を見つけました。

「5、2、1、4」はIDのランダムな順序にすぎないため、これを任意のフィールドとキーに置き換えることができます。

function HOOK_views_post_build ($view) {
  if ($view->name == 'my_view' && $view->current_display == 'my_display') {
      $view->build_info['query']->orderBy("FIELD(id,5,2,1,4)", 'ASC');
    }
  }
}
0
Andrew Thornton