tp5.1--union

UNION操作用于合并两个或多个 SELECT 语句的结果集。

使用示例:

Db::field('name')

->table('think_user_0')

->union('SELECT name FROM think_user_1')

->union('SELECT name FROM think_user_2')

->select();

复制

闭包用法:

Db::field('name')

->table('think_user_0')

->union(function ($query) {

$query->field('name')->table('think_user_1');

})

->union(function ($query) {

$query->field('name')->table('think_user_2');

})

->select();

或者

Db::field('name')

->table('think_user_0')

->union([

'SELECT name FROM think_user_1',

'SELECT name FROM think_user_2',

])

->select();

支持UNION ALL 操作,例如:

Db::field('name')

->table('think_user_0')

->unionAll('SELECT name FROM think_user_1')

->unionAll('SELECT name FROM think_user_2')

->select();

或者

Db::field('name')

->table('think_user_0')

->union(['SELECT name FROM think_user_1', 'SELECT name FROM think_user_2'], true)

->select();

每个union方法相当于一个独立的SELECT语句。

UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。

 

 

 

举例子

表:

 

ff_detail表结构:

 

ff_detail_201804等表结构:

 

需求:

ff_detail表会统计昨天一个订单中包含的设备的播放情况,pic_id代表设备id,date代表日期,play_time点播放次数。ff_detail_201805等为分表记录的是每个小时设备的播放情况,播放一次记录一次。因为数据特别巨大,所有会按照年月生成“ff_detail_年月”形式的分表。需求是按照日期统计每个订单每天播放次数。

代码:


/**

* 根据订单号统计播放次数

* @param string $orderId 订单号(子订单号)

* @param string $page

* @return mixed|false|array

*/

public function getCount($orderId=''){

    if(empty($orderId)){

        return false;

    }

    $picArr=Db::name('pic')->where('order_id',$orderId)->column('id,pic_id');

    if(empty($picArr)){

        return false;

    }

    $picIds=[];

    foreach ($picArr as $pa){

        $picIds[]=$pa['id'];

    }

    if(empty($picIds)){

        return false;

    }

    $nowMonthDate=date('Ymd');

    $nowMonth=date('Ym');
    
    $selectTable='detail_'.$nowMonth;

    $sqlArr=[];

    //昨天之前的数据

    $allDetail=Db::name('detail')
    ->where(['pic_id'=>['in',$picIds]])->field("sum(play_time) as timesum,date")
    ->group('date')->buildSql();

    $sqlArr[]=$allDetail;

    //今天的数据

    $cpmMonthDetail=Db::name($selectTable)
    ->where(['pic_id'=>['in',$picIds],'create_date'=>$nowMonthDate])
    ->field("count(id) as timesum,create_date as date")
    ->group('create_date')->buildSql();

    $sqlArr[]=$cpmMonthDetail;

    //tp5有个问题,用了union之后用where和分页有有问题,所有通过构建子查询来达到目标。子查询里面本身要写完整的查询(指把所有需要查询的都union起来),再通过一个中间表(detail_temp)来组建查询ORM。

    $temp=Db::name('cpm_detail_temp')
    ->field("count(id) as timesum,create_date as date")->union($sqlArr)->buildSql();

    $finall = Db::table($temp." a")

    ->where(['timesum'=>['neq',0],'date'=>['neq',0]]) //把中间表数据过滤掉

    ->order('date desc')

    ->paginate(10,false,[

        'type' => 'Bootstrap',

        'var_page' => 'page',

        'child_order_id'=>$orderId,

        'path'=>"javascript:AjaxPage($orderId,[PAGE]);",

    ]);

    $arrData=$finall->toArray();

    $arrData=$arrData['data'];

    if(!empty($arrData)){

        foreach ($arrData as &$val){

            $val['date']=date('Y-m-d',strtotime($val['date']));

        }

    }

    return empty($finall)?false:['page'=>$finall->render(),'data'=>$arrData];

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值