Views3和子查询?


12

我有一个视图,该视图生成执行多个联接的查询。这将产生笛卡尔连接,而我需要将连接“转换”为子查询。

我浏览了文档,Google搜索结果和其他来源,但是找不到关于如何配置Views进行子查询的任何恰当的描述。我已经使用hook_views_data()来配置关系(现在作为连接执行)。是否可以通过hook_views_data()定义子查询,还是我需要采取另一种方法?

任何建议表示赞赏!

Answers:


5

我进一步看了一下,但实际上找不到任何描述此内容的文档。

我需要的是一种将users表与其他两个为用户保存数据的表联接的方法。但是,其他两个表与用户表之间存在“一对多”关系,这意味着如果我尝试同时将用户表与这两个表连接在一起,将导致笛卡尔连接。但是,由于我只需要计算与任何给定用户关联的其他两个表中的记录数,因此子查询应该可以解决问题。但是,我找不到有关视图和子查询的任何文档-所以这就是我所做的。

  1. 创建了两个虚拟字段

我通过hook_views_data()创建了两个虚拟字段(我将其称为“下载”和“监听”)。字段的定义在下面列出。

function hook_views_data() {

  $data['users'] = array(
    'downloads' => array(
      'title' => t('Downloads'),
      'field' => array(
        'handler' => 'views_handler_field_numeric',
        'click sortable' => TRUE,
      ),
      'filter' => array(
        'handler' => 'views_handler_filter_numeric',
      ),
      'sort' => array(
        'handler' => 'views_handler_sort',
      ),
    ),
    'listens' => array(
      'title' => t('Listens'),
      'field' => array(
        'handler' => 'views_handler_field_numeric',
        'click sortable' => TRUE,
      ),
      'filter' => array(
        'handler' => 'views_handler_filter_numeric',
      ),
      'sort' => array(
        'handler' => 'views_handler_sort',
      ),
    )
  ),
);

现在,当您为用户配置视图时,将出现“下载”和“监听”字段。但是,现在尝试运行查询将导致错误,因为虚拟字段毕竟是虚拟字段。它们不存在。这些字段的唯一目的是向我们的hook_views_query_alter()实现发送信号,它需要执行一些替换菜单。

  1. 实现hook_views_query_alter()

这里的技巧是检查给定查询是否包含“下载”或“侦听”字段。如果是这样,我们将从查询中删除字段并将其替换为子查询。该功能的实现如下。

function mta_views_query_alter(&$view, &$query) {

  foreach ($query->fields as $field_key => &$field_values) {
    if ($field_values['table'] == 'users') {

      switch ($field_values['field']) {
        case 'downloads':
          unset($query->fields[$field_key]);
          $query->add_field(null, "(SELECT COUNT(*) FROM {fileusage} fu WHERE fu.externaluser = {users}.uid AND fu.action = 0)", $field_key);
          break;
        case 'listens':
          unset($query->fields[$field_key]);
          $query->add_field(null, "(SELECT COUNT(*) FROM {fileusage} fu WHERE fu.externaluser = {users}.uid AND fu.action = 1)", $field_key);
          break;
      }
    }
  }
}

请注意,我们正在为子查询重用已删除字段的别名。这样,Views会认为从子查询返回的值实际上来自虚拟字段(毕竟不存在)。

那是。我们没有得到笛卡尔联接,并且“下载”和“监听”都正确计数。


4

在需要子查询继承过滤器值之前,我一直使用sbrattla的解决方案。现在,我使用views_field_view模块嵌入执行计数查询的单独视图。我可以通过上下文过滤器值,以经由嵌入式视图 views_filterfield模块,使得可作为视场(从而令牌)滤波器值(我写)。

计数查询现在可以工作并继承主查询上公开的筛选器。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.