2014-09-19 83 views
3

我在使用“laravel方式”添加多个联合查询时出现问题。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"; 
} 

我还没有找到一个选项,雄辩的工会,所以我尝试使用查询生成器此特定的部分,但我在使用builder的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? 感谢您的期待!

+0

我有同样的问题,请分享,如果你找到了解决办法。 – mshakeel 2016-01-12 13:40:04

回答

9

你的unionAll调用确实是嵌套的。一种解决方案是在for循环中创建一个子查询,然后在之后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)...

,而不是嵌套它们:

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

+0

这样做。感谢您的澄清! – 2014-09-19 21:00:24

1

//使用PDO。这是最简单的答案后,我挣扎在Laravel使用复杂的UNION

$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); 

// JSON响应

 [ 
      { 
        "id": "247", 
        "created_at": "2016-02-23 10:44:33", 
        "updated_at": "2016-02-23 16:58:57", 
        "t_user_account_id": "245", 
        "statement_date": null, 
        "due_date": "0000-00-00 00:00:00", 
        "amount": "0", 
        "is_paid": "0", 
        "is_reminded": "1", 
        "overdue": null, 
        "current_amount": null, 
        "bill_total": "88.5", 
        "bill_id": "zd91NwGU", 
        "bill_name": "Utility", 
        "predecessor": null, 
        "reference_id": "120", 
        "service_provider": "FOLDER", 
        "sp_id": null 
        }, 

      { 
        "id": "252", 
        "created_at": "2016-02-23 16:29:50", 
        "updated_at": "2016-02-23 16:58:25", 
        "t_user_account_id": "250", 
        "statement_date": null, 
        "due_date": "2016-03-04 17:52:34", 
        "amount": "0", 
        "is_paid": "0", 
        "is_reminded": "1", 
        "overdue": null, 
        "current_amount": null, 
        "bill_total": "88.5", 
        "bill_id": "Lojnc", 
        "bill_name": "Water bill", 
        "predecessor": null, 
        "reference_id": "120", 
        "service_provider": "IWK", 
        "sp_id": "7" 
        } 

        ] 
+1

这可行,但它太多了。你可以使用DB :: select(“ANY RAW QUERY HERE”); – 2017-04-24 02:00:54

1

这工作了两天发现,但它是太多了。你可以使用DB :: select(“ANY RAW Query”);