php MySql连接语句顺序(使用Eloquent ORM)

0sgqnhkj  于 2022-12-10  发布在  PHP
关注(0)|答案(2)|浏览(137)

我在项目中使用Laravel Eloquent ORM
为了创建不同的查询,我需要复制一个基本查询,作为一个副产品,我对一些JOIN语句的顺序有问题。
为了简化问题,下面的查询显示了我遇到的问题:

SELECT *
FROM A
JOIN C ON C.x = B.x
JOIN B ON B.y = A.y;

执行此查询时,出现以下错误:

ERROR 1054 (42S22): Unknown column 'B.x' in 'on clause'

我假设原因是当SQL解析器到达第一个连接时,表B还没有包含在内。但是,如果我切换这两行代码,代码会变得非常笨拙(请参阅最后的说明)。
是否有任何方法可以执行这种格式的查询?
或者,有没有办法使用雄辩的查询构建器在第一个连接语句之前注入第二个连接语句?

为什么我无法切换JOIN顺序?

我有一个基本查询,它对于我需要执行的不同查询是通用的:

SELECT * FROM A
JOIN C ON C.x = B.x

第二个JOINB数据表)的索引键取决于我想要执行的最后查询。例如,我可能有:

:
JOIN B ON B.y = A.y1

在另一个查询中:

:
JOIN B ON B.y = A.y2

在雄辩的(非常简化的)代码看起来像:

$baseQuery = DB::table('A')->join('C', 'C.x', '=', 'A.x');

$query1 = (clone $baseQuery)->join('B', 'B.y', '=', 'A.y1');
$query2 = (clone $baseQuery)->join('B', 'B.y', '=', 'A.y2');
ghhkc1vu

ghhkc1vu1#

从 * 上的联接B中选择 *.y = A.y联接C上的联接C.x = B.x;
如果您以这种方式运行上面的查询,它将返回相同的结果。

5vf7fwbs

5vf7fwbs2#

我假设这是一个非常具体的问题,但我会在这里张贴我的解决方案希望这有助于某人的一天.
同样,我构建的查询比示例中的查询大得多,因此我一直在寻找一种避免重复代码的解决方案。
我找到的解决方案是创建一个函数来添加查询的公共部分:

public function myFunc()
{
    $baseQuery = DB::table('A');

    $query1 = (clone $baseQuery)->join('B', 'B.y', '=', 'A.y1');
    $query2 = (clone $baseQuery)->join('B', 'B.y', '=', 'A.y2');

    $this->addCommonQueryPostfix($query1);
    $this->addCommonQueryPostfix($query2);
}

private function addCommonQueryPostfix(\Illuminate\Database\QueryBuilder &$query)
{
    $query->join('C', 'C.x', '=', 'B.x');
}

这将按预期创建以下查询:

SELECT * FROM A INNER JOIN B ON B.y = A.y1 INNER JOIN C ON C.x = B.x;
SELECT * FROM A INNER JOIN B ON B.y = A.y2 INNER JOIN C ON C.x = B.x;

相关问题