Hook_views_query_alter () içindeki `` GROUP BY` '' neden çalışmıyor?


11

Views 7.x-3.6 kullanıyorum ve GROUP BYmaddeyi hook_views_query_alter()aşağıdaki gibi değiştirmeye çalıştım :

function mymodule_views_query_alter(&$view, &$query) {
    if ($view->name == "view_name"){
      $query->add_groupby('field_name');
      dpm($query);    
    }
}

Ben baktığım zaman $query, fıkra doğru etkindir ancak SQL sorgusu etkilenmez : fıkra görünmüyor:groupbyGROUP BY

resim açıklamasını buraya girin

Sonunda ne yaptım bir Drupal çekirdek kanca ( hook_query_alter()) kullanmak ve iyi çalıştı: SQL şimdi etkilenir.

function mymodule_query_alter(QueryAlterableInterface $query) {
  $view_name = 'view_name';
  if ($query->hasTag('views_' . $view_name)) {    
    $query->groupBy('field_name');
  }
}

Çalışmamın bir nedeni var hook_views_query_alter()mı? Bunu yapmanın daha temiz bir yolu olup olmadığını merak ediyorum ve.

Yanıtlar:


11

Parametre add_field()ile kullanın array('function' => 'groupby').

$query->add_field('node', 'nid', 'node_nid', array('function' => 'groupby'));
$query->add_groupby('node.nid');

Ek bilgi:

Kullandıktan sonra add_groupbyaşağıdaki kodu görebilirsiniz GROUP BY:

GROUP BY node.nid, nid

Sonraki sayıya bakın: https://drupal.org/node/1578808

Gereksiz GROUP BY koşullarından kaçınmak için şunu ekleyin:

$query->distinct = TRUE;

1
$ Query-> differentt = TRUE eklemeden gereksiz grubu nasıl kaldırabiliriz;
ARUN

Ben birkaç saat grup hata ayıklama geçirdi. Ama şu anda başka bir çözüm bilmiyorum.
milkovsky

Yorumun için teşekkürler. hmm .. soruyorum çünkü, eğer $ query-> eklersek> = TRUE; sonra nidgruplandırma grubu ile eklenecektir . Benim için gerekli değil. Başka bir seçenek var mı? Görüntüleme sorgusunda benzersiz nasıl ekleneceğini biliyor musunuz?
ARUN

Bu views_handler_filter::query()afairdi. Deneyin $query->distinct();içindehook_query_alter
milkovsky

1

Partiye geç ama bu başka birine yardımcı olabilir.

Benim durumumda Taksonomi Terim alanı ( https://drupal.org/node/1808320 ) olan kullanıcıların bir listesini (ek modül Profile2 kullanarak) veriyordum . Views 3 API'sından kurtulamadığım birden çok sonuç görüyordum.

Özel modülüme ekledim:

/**
    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 parametreleri

add_field(TABLE_NAME, FIELD, FIELD_ALIAS, array('function' => 'groupby'))

1

Hala sorguya gereksiz GROUP BY ifadeleri ile karşı karşıyaysanız, bunları kaldırabilirsiniz hook_query_alter(). Örneğin en çok yorum yapılan ebeveyn yorumları tarafından yorum siparişi vermekle ilgili sorunu çözdüm.

Yani hook_views_query_alter()bende:

/**
 * 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]);
  }
}

Tarafından gruplandırılamamayla ilgili hata aldım

comments_count

aslında SQL COUNT()işlevinin bir sonucu .

Ben bununla sona erdi:

/**
 * 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]);
      }
    }
  }
}

0

Hook_views_query_alter dokümantasyonuna bakarsanız , sorgunun zaten çalışmaya hazır olduğuna inanıyorum. Örneğin, veritabanı API'si tarafından değiştirmeler yapıldı ve kablo üzerinden MySQL'e gönderilmek üzere. Hook_views_query_alter kullanımına başka bir örnek BTMash blogunda görülebilir .

Bu artık bir DB Sorgu Nesnesi değil, bir Array olarak ifadeler, değişkenler, vb SQL ifadelerinin parçaları olması durumudur.

Önümde bir sorgu yok ama aşağıdaki test edilmemiş kod gibi bir şey ne istiyorsun:

$query->groupby[0]['field'] = 'field_name';

Cevabınız için teşekkürler! Denedim ama o da çalışmıyor: tekrar, $querynesne (tabii ki yukarıdakinden farklı) değiştirilir ama yine, SQL sorgusu değişmez!
jozi

Farklı bir manzara kancası denedin mi? _pre_render veya _pre_build? .... hook_views_pre_execute () denerdim
tenken

0

Views_query_alter içinde böyle yapılır; node_access parçası gerekli değildir.

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');    
  }
}

0

Kimsenin sadece işe yarayan gerçek bir çözüm sağlamadığını merak ettim. Burada bulduğum böyle bir yöntem var , @ b-ravanbakhsh'a çok teşekkürler:

/**
 * 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');
    }
  }
}

0

Drupal 8'de ve graceman9 yaklaşımı sayesinde:

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');
    }
  }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.