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関数を追加するにはどうすればよいですか?特定のフィルター値を結果キューの一番下にプッシュする別の方法はありますか?
私はこれを手に入れました! orderBy
をhook_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');
}
}
以前の答えに基づいて構築(ありがとう)。私は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');
}
}
}