BlueSnow,动物界-脊索动物门-脊椎动物亚门-哺乳动物纲-灵长目-类人猿亚目-狭鼻猴次目-人猿超科-人科-人属-智人种、雄性、昼伏夜出、喜独居、杂食,1996年至今一直作为程序员生活,恋过爱、失过恋、结了婚、有了儿子。

使用 hook_views_query_alter 修改 views 的sql语句

BlueSnow 提交于 周五, 03/04/2016 - 15:29

目标:输出一个表格,能够按照日期统计用户发表“文章的篇数”,要求列出所有用户名(包括发表数为0的用户)

53s0fd2gi11y0o2u1lsk8i.jpg思路:

第一步,创建基于用户{user}表的views;关联 {node}表;字段:用户名,(发表文章的)nid ,并对nid使用COUNT(DISTINCT)聚合计算篇数;filter node.created 并且exposed。

 eioalb2esx58iu5pnt.jpg

预览结果(发表数量为0的用户没有现实出来)

hmtcaq6a77ox4ksw.jpg第二步,修改sql语句

分析sql语句,

from {user} u left join {node} n on n.uid=u.uid WHERE n.created = 2014-3-27。

使用left join 左表应该全部现实才对,问题出在了where 语句的使用上。

在使用left jion时,on和where条件的区别 (link is external)如下:
1、 on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。
2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。

要想实现目标 ,需要的sql语句,应该是

from {user} u left join {node} n on n.uid=u.uid AND n.created = 2014-3-27。

创建一个模块,使用Hook_views_query_alter修改sql语句,查看hook_views_query_alter (link is external)

This hook should be placed in MODULENAME.views.inc and it will be auto-loaded. MODULENAME.views.inc must be in the directory specified by the 'path' key returned by MODULENAME_views_api(), or the same directory as the .module file, if 'path' is unspecified.

 

开始创建模块,模块名称 mymodule

mymodule.info

 

name = mymodule
core = 7.x
description = ''
package = Views

-------------------------------------

mymodule.module

 

<?php
function mymodule_views_api(){
    return array(
        'api' => 3,
        //(必须) views的版本,我使用的是7.x-3.7版本
        //'path' => drupal_get_path('module', 'example') . '/includes/views',
        //(可选) 如果文件不在模块文件根目录下,说明一下文件路径。
        //'template path' => drupal_get_path('module', 'example') . '/themes',
        //(可选)模板文件路径
    );
}

--------------------------------------

mymodule.views.inc

 

<?php
//hook_views_query_alter
function mymodule_views_query_alter(&$view, &$query) {    
    if($view->name == "views_custom_sql" && $view->current_display == "page"){

               //我创建的views 的机器名称为 views_custom_sql,这里替换
              //在这里你可以对$query进行修改,使用dpm($query)

            
        $query->table_queue['node_users']['join']->extra = array(
            0=>array(
                'table'=>"DATE_FORMAT(CONVERT_TZ(FROM_UNIXTIME(node_users",
                'field'=>"created), 'UTC', 'Asia/Shanghai'), '%Y-%m-%d')",
                'value'=>$query->where[1]['conditions'][1]['value']
            )
        );
        unset($query->where[1]['conditions'][1]);//清除where语句中node.created的条件
       //dpm($query); 
    }
}

修改前

c60q4r75fqc09tgyx.jpg

 

 

修改后

m_11mgg5_ypj6nzzedc.jpg

在此感谢 yes湛江-nemo给我的多次帮助!