雄辩的查询替代方案

时间:2015-03-13 11:18:38

标签: laravel eloquent

如何在Laravel的Eloquent中写下以下内容?

SELECT *
FROM
  ( SELECT real_estate.property_id,
           real_estate.amount_offered,
           payee.summa
   FROM real_estate
   LEFT JOIN
     (SELECT property_id,
             SUM(amount) AS summa
      FROM payments
      GROUP BY property_id) payee ON payee.property_id = real_estate.property_id ) yoot
WHERE summa = 0.05 * amount_offered

现在已经有一段时间了,真的无法绕过它。勒梅解释了恐慌的全部原因。

我有两个表,一个用于属性,另一个用于对这些属性进行的付款。现在,在任何给定的时间,我都想查询已支付的特定百分比的属性,因此0.05代表5%。因为它是查询工作,但我需要一个雄辩的替代品。感谢

1 个答案:

答案 0 :(得分:2)

在您的SQL中有子查询的任何地方,您都需要将DB::raw与Eloquent一起使用。在这种情况下,您有一个用于FROM语句的大子查询,因此最简单的方法是执行此操作:

DB::table(
    DB::raw('SELECT real_estate.property_id, real_estate.amount_offered, payee.summa FROM real_estate LEFT JOIN (SELECT property_id, SUM(amount) AS summa FROM payments GROUP BY property_id) payee ON payee.property_id = real_estate.property_id)')
)
->where('summa', DB::raw('0.05 * amount_offered'))->get();

注意我也使用了DB::raw作为WHERE身份值。这是因为您使用列名进行乘法运算,否则该值将被引用为字符串。


如果你想更进一步使用Eloquent构建每个子查询,然后将其转换为SQL字符串并使用DB::raw注入它,你可以这样做:

$joinQuery = DB::table('payments')
    ->select('property_id', 'SUM(amount) AS summa')
    ->groupBy('property_id')
    ->toSql();

$tableQuery = DB::table('real_estate')
    ->select('real_estate.property_id', 'real_estate.amount_offered', 'payee.summa')
    ->leftJoin(DB::raw('(' . $joinQuery . ')'), function ($join)
    {
        $join->on('payee.property_id', '=', 'real_estate.property_id');
    })
    ->toSql();

DB::table(DB::raw('(' . $tableQuery . ')'))->where('summa', DB::raw('0.05 * amount_offered'))->get();

在这种情况下,第二种方法与第一种方法相比没有任何好处,除非它更具可读性。但是,使用Eloquent构建子查询,当您需要将任何变量值绑定到查询(例如条件)时,确实有它的好处,因为查询将由Eloquent正确构建和转义,你会不容易出现SQL注入。