私はビュー7.x-3.6を使用していて、以下のように hook_views_query_alter()
を使用して_GROUP BY
_句を変更しようとしました:
_function mymodule_views_query_alter(&$view, &$query) {
if ($view->name == "view_name"){
$query->add_groupby('field_name');
dpm($query);
}
}
_
_$query
_を見ると、groupby
句が正しく有効になっていますが、 SQLクエリは影響を受けません:_GROUP BY
_句は表示されません。
私がやったことは、Drupalコアフック( hook_query_alter()
)を使用することで、うまくいきました。SQLが影響を受けています。
_function mymodule_query_alter(QueryAlterableInterface $query) {
$view_name = 'view_name';
if ($query->hasTag('views_' . $view_name)) {
$query->groupBy('field_name');
}
}
_
hook_views_query_alter()
が機能しない理由は何ですか?それを行うためのよりクリーンな方法があるかどうかと思います。
add_field()
をarray('function' => 'groupby')
パラメータとともに使用します。
$query->add_field('node', 'nid', 'node_nid', array('function' => 'groupby'));
$query->add_groupby('node.nid');
追加情報:
add_groupby
を使用すると、GROUP BY
の後に次のコードが表示される場合があります。
GROUP BY node.nid, nid
次の問題を参照してください: https://drupal.org/node/1578808
不要なGROUP BY条件を回避するには、以下を追加します。
$query->distinct = TRUE;
クエリに追加された不要なGROUP BYステートメントにまだ直面している場合は、hook_query_alter()
でそれらを削除できます。たとえば、ほとんどのコメント付き親コメントによるコメントの順序付けの問題を解決しました。
hook_views_query_alter()
では、
_/**
* Implements hook_views_query_alter().
*/
function MODULENAME_views_query_alter(&$view, &$query) {
if ($view->name == 'reviews' && $query->orderby[0]['field'] == 'comment_thread') {
$join = new views_join;
$join->construct('comment', 'comment', 'cid', 'pid', NULL, 'LEFT');
$query->add_relationship('c1', $join, 'comment');
$query->add_field('comment', 'pid', 'c1_pid', array('function' => 'groupby'));
$query->add_groupby('c1.pid');
$query->add_orderby(NULL, 'COUNT(c1.cid)', 'DESC', 'comments_count');
$query->distinct = TRUE;
$query->orderby[0] = $query->orderby[count($query->orderby) - 1];
unset($query->orderby[count($query->orderby) - 1]);
}
}
_
グループ化できないことに関連するエラーが発生しました
コメント数
実際にはSQL COUNT()
関数の結果であるフィールド。
私はこれで終わりました:
_/**
* Implements hook_query_alter().
*/
function MODULENAME_query_alter(QueryAlterableInterface $query) {
if (isset($query->alterMetaData['view']->name) && $query->alterMetaData['view']->name == 'reviews') {
$fields =& $query->getGroupBy();
foreach (array_keys($fields) as $key) {
// Remove group by statements from generated query which were actually not set in view query.
if (!in_array($key, $query->alterMetaData['view']->query->groupby)) {
unset($fields[$key]);
}
}
}
}
_
パーティーに遅れますが、これは他の誰かを助けるかもしれません。
私の場合、ユーザーのリストを(追加モジュールProfile2を使用して)分類用語フィールド( https://drupal.org/node/180832 )で提供していました。 Views 3 APIで取り除くことができない複数の結果が表示されました。
私のカスタムモジュールに追加しました:
/**
Implementation of hook_views_query_alter()
**/
function MYMODULE_views_query_alter(&$view, &$query) {
if($view->name == "provider_results_list" && $view->current_display == "page_1") {
$query->distinct = TRUE;
// User the provider uid to make the results distinct: using a taxonomy field for
// keyword searches brings up multiple results.
$query->add_field('profile', 'uid', 'provider_uid', array('function' => 'groupby'));
}
}
Add_fieldのパラメーターは次のとおりです。
add_field(TABLE_NAME, FIELD, FIELD_ALIAS, array('function' => 'groupby'))
Drupal 8では、graceman9アプローチのおかげで、次のようになります。
use Drupal\Core\Database\Query\AlterableInterface;
function MYMODULE_query_alter(AlterableInterface $query) {
if (isset($query->alterMetaData['view'])) {
if($query->alterMetaData['view']->id() == 'replace_by_view_machine_name') {
// Group by UID to remove duplicates from View results
$query->groupBy('users_field_data.uid');
// If multilingual site, you should add the following
// $query->groupBy('users_field_data.langcode');
}
}
}
誰もがうまく機能する実際のソリューションを提供していないのではないかと思いました。私が見つけたそのような方法が1つあります here 、@ b-ravanbakhshに感謝します:
/**
* Implements hook_query_alter().
*/
function MODULENAME_query_alter(QueryAlterableInterface $query) {
if (isset($query->alterMetaData['view'])) {
if($query->alterMetaData['view']->name == 'YOUR_VIEW_NAME'){
// also you can unset other group by critera by using, unset($query->getGroupBy());
$query->groupBy('users.uid');
}
}
}
これは、views_query_alterで行われる方法です。 node_access部分は必要ありません。
function xdas_target_audience_views_query_alter(&$view, &$query) {
$controlled_views = variable_get('xdas_target_audience_views', array(
'landing_products',
'promotions',
'landing_coupons',
'landing_coupons_belvita',
'landing_coupons_lulu',
'related_coupon',
'cuponazo',
'banner',
'brands',
));
if (in_array($view->name, $controlled_views) && $view->base_table == 'node') {
//add node_access to views so we can control access.
$query->add_tag('node_access');
$join = new views_join();
$join->construct('xdas_target_audience_boost', 'node', 'nid', 'nid');
$query->add_relationship('xdas_target_audience_boost', $join, 'node');
$query->add_field('xdas_target_audience_boost', 'score', 'score' , array('function' => 'max'));
$query->add_orderby(NULL, NULL, 'DESC', 'score');
$query->add_groupby('nid');
}
}
hook_views_query_alter のドキュメントを見ると、クエリを実行する準備が整っていると思います。たとえば、データベースAPIによって置き換えが行われ、有線でMySQLに送信されます。別の hook_views_query_alterの使用例は、BTMashブログで確認できます 。
これは、DBクエリオブジェクトではなく、式や変数などを配列として含むSQLステートメントの一部である場合です。
私の前にクエリはありませんが、次のテストされていないコードのようなものがあなたが望むものです:
$query->groupby[0]['field'] = 'field_name';