【问题标题】:WHERE clause with relationship to another table in Laravel与 Laravel 中另一个表的关系的 WHERE 子句
【发布时间】:2017-12-31 08:52:17
【问题描述】:

我的 Laravel 应用程序中有几个表,一个称为 shipping,另一个称为 payment_distributions。

在我的货件中,我有名为 pro_number 和 balance 的列。

在我的 payment_distributions 中,我有名为 shipping_id 和 amount 的列。

现在我有一个控制器,其中包含这部分代码:

}elseif($_GET['paymentStatus']=="Unpaid"){
    if(empty($_GET['pro_number'])){
            $shipment = NULL;
        }else{
        $shipment = $_GET['pro_number'];
        }

        if($_GET['startDate']){
            $startDate = $_GET['startDate'];
        }
        if($_GET['endDate']){
            $endDate = $_GET['endDate'];
        }
                $start = $_GET['startDate'];
                $end = $_GET['endDate'];
                $status = $_GET['paymentStatus'];
    $date = \Carbon\Carbon::today()->subDays(0);

    $shipments = Shipment::sortable()
    ->where([
        ['due_date','<=',date($date)],
        ['pro_number', 'LIKE', '%' . $shipment . '%'],
        ['balance','>','SELECT SUM(payments_distributions.amount) FROM payments_distributions WHERE payments_distributions.shipment_id = pro_number'],
    ])
    ->whereBetween('date', [$startDate, $endDate])
    ->whereNotIn('shipment_billing_status', [2,3])
    ->paginate(25);
    return view('shipments.accounts', compact('shipments','start','end','status'));

}

现在我的问题出现了,如果我将以下代码放入 MYSQL 中,则它可以工作:

SELECT SUM(payments_distributions.amount) FROM payments_distributions WHERE payments_distributions.shipment_id = 214050

将返回 SUM(payments_distributions.amount): 300.00

所以,如果您转到我的代码中的行,这是唯一不起作用的东西,所以如果可以的话,这行代码对每个人来说都是正确的吗?我想说的是,发货行中的余额字段必须大于 payment_distributions 表中的 amount 字段之和,其中 payment_distributions 表中的 shipping_id 字段等于发货表中的 pro_number 字段。

 ['balance','>','SELECT SUM(payments_distributions.amount) FROM payments_distributions WHERE payments_distributions.shipment_id = pro_number'],
    ]

更新(整个函数)

public function accountsQuery(){


if(($_GET['paymentStatus'] == "No Settle") or ($_GET['paymentStatus'] == "No Charge")){
            if($_GET['paymentStatus'] == "No Settle"){
                $status = 3;
            }elseif($_GET['paymentStatus'] == "No Charge"){
                $status = 2;
            }
                if(empty($_GET['pro_number'])){
                $shipment = NULL;
                }else{
                $shipment = $_GET['pro_number'];
                }

                if($_GET['startDate']){
                    $startDate = $_GET['startDate'];
                }
                if($_GET['endDate']){
                    $endDate = $_GET['endDate'];
                }
                        $start = $_GET['startDate'];
                        $end = $_GET['endDate'];
                        $status = $_GET['paymentStatus'];
                        $shipments = \App\Shipment::sortable()->where([ 
                            ['pro_number', 'LIKE', '%' . $shipment . '%'],
                            ['shipment_billing_status', 'LIKE', '%' . $status . '%'],
                        ])
                            ->whereBetween('date', [$startDate, $endDate])
                            ->paginate(25);
                return view('shipments.accounts', compact('shipments','start','end','status'));

}elseif($_GET['paymentStatus']=="Billed"){
    if(empty($_GET['pro_number'])){
            $shipment = NULL;
        }else{
        $shipment = $_GET['pro_number'];
        }

        if($_GET['startDate']){
            $startDate = $_GET['startDate'];
        }
        if($_GET['endDate']){
            $endDate = $_GET['endDate'];
        }
                $start = $_GET['startDate'];
                $end = $_GET['endDate'];
                $status = $_GET['paymentStatus'];
    $date = \Carbon\Carbon::today()->subDays(30);
    //AND TO MENTION WHERE SUM OF PAYMENTS TO THIS SHIPMENT < BALANCE DUE
    $shipments = Shipment::sortable()
    ->where([
        ['date','>=', date($date)],
        ['pro_number', 'LIKE', '%' . $shipment . '%'],
    ])
    ->whereBetween('date', [$startDate, $endDate])
    ->paginate(25);
    return view('shipments.accounts', compact('shipments','start','end','status'));

}elseif($_GET['paymentStatus']=="Unpaid"){
    if(empty($_GET['pro_number'])){
            $shipment = NULL;
        }else{
        $shipment = $_GET['pro_number'];
        }

        if($_GET['startDate']){
            $startDate = $_GET['startDate'];
        }
        if($_GET['endDate']){
            $endDate = $_GET['endDate'];
        }
                $start = $_GET['startDate'];
                $end = $_GET['endDate'];
                $status = $_GET['paymentStatus'];
    $date = \Carbon\Carbon::today()->subDays(0);

    $shipments = Shipment::sortable()
    ->where([
        ['due_date','<=',date($date)],
        ['pro_number', 'LIKE', '%' . $shipment . '%'],
    ])
    ->whereRaw('balance > SELECT SUM(p.amount) FROM payments_distributions p WHERE p.shipment_id = pro_number')
    ->whereBetween('date', [$startDate, $endDate])
    ->whereNotIn('shipment_billing_status', [2,3])
    ->paginate(25);
    return view('shipments.accounts', compact('shipments','start','end','status'));

}  
}

【问题讨论】:

  • 尝试使用 DB::raw() 调用围绕内部 SELECT(与余额进行比较的地方)。您看到的问题是因为查询生成器将 balance 与包含 SQL 语句的字符串进行比较,而不是 SQL 语句的结果。
  • @Jason - 我已将所有内容更改回原来的内容,现在在我的 where([.... 部分我有以下内容:['balance', '>', DB::raw( 'SELECT IFNULL(SUM(p.amount),0) FROM payment_distributions p WHERE p.shipment_id = shipping.pro_number')], - 但我返回此错误
  • 您的 SQL 语法有错误;检查与您的 MariaDB 服务器版本相对应的手册,以在第 1 行的 'SELECT IFNULL(SUM(p.amount),0) FROM payment_distributions p WHERE p.shipment_id' 附近使用正确的语法(SQL:select count(*) as从 shipments 聚合,其中 (due_date pro_number LIKE %% 和 balance > SELECT IFNULL(SUM(p.amount),0) FROM payment_distributions p WHERE p.shipment_id = shipping.pro_number) 和 date 在 1997-12-01 和 2017-12-26 之间和 shipment_billing_status 不在 (2, 3)) 中

标签: php mysql laravel laravel-5


【解决方案1】:

您应该能够将该子查询用作whereRaw 表达式的一部分:

->where([
    ['due_date','<=',date($date)],
    ['pro_number', 'LIKE', '%' . $shipment . '%']])
->whereRaw('balance > SELECT SUM(p.amount) FROM payments_distributions p WHERE p.shipment_id = pro_number')
->whereBetween('date', [$startDate, $endDate])
...

但是,我怀疑我们可能会重写您的查询,以取消 WHERE 子句中的相关子查询。

【讨论】:

  • SQLSTATE[42000]:语法错误或访问冲突:1064 您的 SQL 语法有错误;检查与您的 MariaDB 服务器版本相对应的手册,以在第 1 行的“SELECT SUM(p.amount) FROM payment_distributions p WHERE p.shipment_id = pro_num”附近使用正确的语法(SQL:select count(*) as aggregate from @ 987654324@ where (due_date pro_number LIKE %%) and balance > SELECT SUM(p.amount) FROM payment_distributions p WHERE p.shipment_id = pro_number and date在 1997 年 12 月 1 日和 2017 年 12 月 25 日之间,shipment_billing_status 不在 (2, 3) 中)
  • 我正在使用你建议的 whereRaw,我知道你一定很接近,你有什么建议让我尝试解决吗?我会继续尝试,如果我能找到什么,我会告诉你。再次感谢 - 马特
  • @Matthew 错误输出似乎来自与您的问题略有不同的查询。您可以使用您正在运行的实际查询来编辑您的问题吗?根据我的阅读,我对whereRaw 的使用是合法的。
  • 实际上对于被引用的部分,它们是相同的查询。我可以发布整个功能,但目前我发送的只是“paymentStatus”=“Unpaid”。我将发布整个功能,
  • 更好的是,也许可以发布原始的 MySQL 查询。我认为我们可以用不需要whereRaw 的方式来表达它。
猜你喜欢
  • 2021-07-30
  • 1970-01-01
  • 1970-01-01
  • 2016-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多