Laravel多个工会

问题描述 投票:4回答:3

我在使用“laravel方式”添加多个联盟的查询时遇到问题。

我正在尝试完成与以下生成的查询等效的查询:

$ipsql = "";
for ($n = 1; $n < $total_networks; $n++) {
    $ipsql .= "(SELECT * FROM ip WHERE network = " . $n . " AND used = 0 LIMIT 5)
            UNION ALL";
}
if ($n == $total_networks) {
    $ipsql .= "(SELECT * FROM ip WHERE network = " . $n . " AND used = 0 LIMIT 3) ORDER BY ip_addr";
}

我没有为Eloquent找到一个工会选项,所以我试图使用查询构建器来处理这个特定的部分,但是在使用构建器unionAll时我一直遇到问题。

使用这个:

$ip_list = DB::table('ips')->where('network', '=', '0')->where('used', '=', '0')->limit(5);
        for($n = 1; $n < $network_count; $n++){
            $ip_list = DB::table('ips')->where('network', '=', $n)->where('used', '=', '0')->limit(5)->unionAll($ip_list);
        }
        $ips = $ip_list->get();

我一直收到MySQL语法错误:

     SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax;
     check the manual that corresponds to your MySQL server version for the right syntax to use near
     'union all ((select * from `ips` where `network` = ? and `used` = ? limit 5) unio' at line 1 
    (SQL:
         (select * from `ips` where `network` = 16 and `used` = 0 limit 5) union all ((select * from `ips`
         where `network` = 15 and `used` = 0 limit 5) union all ((select * from `ips` where `network` = 14
         and `used` = 0 limit 5) union all ((select * from `ips` where `network` = 13 and `used` = 0 limit 5)
         union all ((select * from `ips` where `network` = 12 and `used` = 0 limit 5) union all ((select *
         from `ips` where `network` = 11 and `used` = 0 limit 5) union all ((select * from `ips` where
         `network` = 10 and `used` = 0 limit 5) union all ((select * from `ips` where `network` = 9 and
         `used` = 0 limit 5) union all ((select * from `ips` where `network` = 8 and `used` = 0 limit 5)
 union all ((select * from `ips` where `network` = 7 and `used` = 0 limit 5) union all ((select * from
         `ips` where `network` = 6 and `used` = 0 limit 5) union all ((select * from `ips` where `network` =
         5 and `used` = 0 limit 5) union all ((select * from `ips` where `network` = 4 and `used` = 0 limit
         5) union all ((select * from `ips` where `network` = 3 and `used` = 0 limit 5) union all ((select *
         from `ips` where `network` = 2 and `used` = 0 limit 5) union all ((select * from `ips` where
         `network` = 1 and `used` = 0 limit 5) union all (select * from `ips` where `network` = 0 and `used`
         = 0 limit 5)))))))))))))))))

我可以从错误中看到它嵌套每个新的联合调用,这会产生语法问题。我尝试用DB :: raw完成相同的任务,但似乎也在某个地方搞砸了。有没有办法实现这个更适合laravel?谢谢你的期待!

php laravel-4
3个回答
10
投票

你的unionAll电话确实是嵌套的。一种解决方案是在for循环中创建子查询,然后在定义之后将qquxswpoi子查询到主查询。然后你在完成时就在整个shebang上运行unionAll,如下所示:

get

所以,实际上,你是在链接$ips_list = DB::table('ips')->where('network', '=', '1')->where('used', '=', '0')->limit(5); for($n = 1; $n < $total_networks; $n++){ $ip_list_subquery = DB::table('ips') ->where('network', '=', $n) ->where('used', '=', '0') ->limit(5); $ips_list = $ips_list->unionAll($ip_list_subquery); } $ips = $ips_list->get(); 电话:

unionAll

而不是嵌套它们:

$a->unionAll($b)->unionAll($c)->unionAll($d)...


1
投票

//使用PDO这是我在Laravel中使用复杂的UNION两天后找到的最简单的答案

$a->unionAll($b->unionAll($c->unionAll($d...))))

// JSON响应

 $PDO = DB::connection('mysql')->getPdo();

 $billingStmt = $PDO->prepare("

 select * from (SELECT   * 
 FROM     t_statements 
 WHERE    reference_id = $user_id 
 AND      service_provider='FOLDER' 
 AND      bill_name IS NOT NULL 
 ORDER BY bill_name ASC ) AS a 

 UNION ALL 

 SELECT * 
 FROM   ( 
 SELECT   * 
 FROM     t_statements 
 WHERE    reference_id = $user_id 
 AND      service_provider !='FOLDER' 
 AND      bill_name IS NOT NULL 
 ORDER BY (CASE WHEN is_paid = 0 THEN due_date ELSE is_paid END) DESC) b

     ");



        $billingStmt->execute();
        $usersBills = $billingStmt->fetchAll((\PDO::FETCH_ASSOC));
        header('Content-Type: application/json');
        $androidUserBills = json_encode($usersBills); // return results as json 

    return response($androidUserBills);

1
投票

这有效但但太多了。你可以使用DB :: select(“ANY RAW Query”);